summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Sedovic <tomas@sedovic.cz>2013-08-08 14:30:46 +0200
committerTomas Sedovic <tomas@sedovic.cz>2013-08-08 15:29:35 +0200
commitfed131db5c2ba09fc9c48ea3303d0cba8a9b881e (patch)
tree59e94658e03c8244263c69f0b657e9119fb75bc7
parent6ff41540a1989a7e4cdc216e289dfe9c733c88e8 (diff)
downloadtuskar-ui-fed131db5c2ba09fc9c48ea3303d0cba8a9b881e.tar.gz
Remove the Horizon-specific files
Signed-off-by: Tomas Sedovic <tomas@sedovic.cz>
-rw-r--r--doc/Makefile153
-rw-r--r--doc/source/conf.py426
-rw-r--r--doc/source/contributing.rst203
-rw-r--r--doc/source/faq.rst37
-rw-r--r--doc/source/glossary.rst24
-rw-r--r--doc/source/index.rst127
-rw-r--r--doc/source/intro.rst124
-rw-r--r--doc/source/quickstart.rst214
-rw-r--r--doc/source/ref/context_processors.rst6
-rw-r--r--doc/source/ref/decorators.rst6
-rw-r--r--doc/source/ref/exceptions.rst6
-rw-r--r--doc/source/ref/forms.rst98
-rw-r--r--doc/source/ref/horizon.rst45
-rw-r--r--doc/source/ref/middleware.rst6
-rw-r--r--doc/source/ref/run_tests.rst233
-rw-r--r--doc/source/ref/tables.rst82
-rw-r--r--doc/source/ref/tabs.rst45
-rw-r--r--doc/source/ref/test.rst25
-rw-r--r--doc/source/ref/workflows.rst33
-rw-r--r--doc/source/releases/2012_1.rst148
-rw-r--r--doc/source/releases/2012_2.rst159
-rw-r--r--doc/source/releases/2013_1.rst274
-rw-r--r--doc/source/testing.rst41
-rw-r--r--doc/source/topics/customizing.rst137
-rw-r--r--doc/source/topics/deployment.rst217
-rw-r--r--doc/source/topics/settings.rst294
-rw-r--r--doc/source/topics/tables.rst129
-rw-r--r--doc/source/topics/testing.rst276
-rw-r--r--doc/source/topics/tutorial.rst556
-rw-r--r--horizon/__init__.py57
-rw-r--r--horizon/base.py803
-rw-r--r--horizon/browsers/__init__.py21
-rw-r--r--horizon/browsers/base.py150
-rw-r--r--horizon/browsers/breadcrumb.py48
-rw-r--r--horizon/browsers/views.py49
-rw-r--r--horizon/conf/__init__.py35
-rw-r--r--horizon/conf/dash_template/__init__.py0
-rw-r--r--horizon/conf/dash_template/dashboard.py.tmpl13
-rw-r--r--horizon/conf/dash_template/models.py3
-rw-r--r--horizon/conf/dash_template/static/dash_name/css/dash_name.css1
-rw-r--r--horizon/conf/dash_template/static/dash_name/js/dash_name.js1
-rw-r--r--horizon/conf/dash_template/templates/dash_name/base.html11
-rw-r--r--horizon/conf/default.py35
-rw-r--r--horizon/conf/panel_template/__init__.py0
-rw-r--r--horizon/conf/panel_template/models.py3
-rw-r--r--horizon/conf/panel_template/panel.py.tmpl13
-rw-r--r--horizon/conf/panel_template/templates/panel_name/index.html12
-rw-r--r--horizon/conf/panel_template/tests.py.tmpl7
-rw-r--r--horizon/conf/panel_template/urls.py8
-rw-r--r--horizon/conf/panel_template/views.py10
-rw-r--r--horizon/context_processors.py44
-rw-r--r--horizon/decorators.py94
-rw-r--r--horizon/exceptions.py321
-rw-r--r--horizon/forms/__init__.py40
-rw-r--r--horizon/forms/base.py57
-rw-r--r--horizon/forms/fields.py77
-rw-r--r--horizon/forms/views.py117
-rw-r--r--horizon/loaders.py48
-rw-r--r--horizon/locale/bg_BG/LC_MESSAGES/django.mobin4526 -> 0 bytes
-rw-r--r--horizon/locale/bg_BG/LC_MESSAGES/django.po514
-rw-r--r--horizon/locale/bg_BG/LC_MESSAGES/djangojs.mobin378 -> 0 bytes
-rw-r--r--horizon/locale/bg_BG/LC_MESSAGES/djangojs.po73
-rw-r--r--horizon/locale/ca/LC_MESSAGES/django.mobin5569 -> 0 bytes
-rw-r--r--horizon/locale/ca/LC_MESSAGES/django.po513
-rw-r--r--horizon/locale/cs/LC_MESSAGES/django.mobin7066 -> 0 bytes
-rw-r--r--horizon/locale/cs/LC_MESSAGES/django.po520
-rw-r--r--horizon/locale/en/LC_MESSAGES/django.mobin4775 -> 0 bytes
-rw-r--r--horizon/locale/en/LC_MESSAGES/django.po514
-rw-r--r--horizon/locale/en/LC_MESSAGES/djangojs.mobin378 -> 0 bytes
-rw-r--r--horizon/locale/en/LC_MESSAGES/djangojs.po73
-rw-r--r--horizon/locale/en_GB/LC_MESSAGES/django.mobin6110 -> 0 bytes
-rw-r--r--horizon/locale/en_GB/LC_MESSAGES/django.po513
-rw-r--r--horizon/locale/es/LC_MESSAGES/django.mobin6939 -> 0 bytes
-rw-r--r--horizon/locale/es/LC_MESSAGES/django.po518
-rw-r--r--horizon/locale/es/LC_MESSAGES/djangojs.mobin420 -> 0 bytes
-rw-r--r--horizon/locale/es/LC_MESSAGES/djangojs.po74
-rw-r--r--horizon/locale/fi_FI/LC_MESSAGES/django.mobin6978 -> 0 bytes
-rw-r--r--horizon/locale/fi_FI/LC_MESSAGES/django.po513
-rw-r--r--horizon/locale/fr/LC_MESSAGES/django.mobin414 -> 0 bytes
-rw-r--r--horizon/locale/fr/LC_MESSAGES/django.po510
-rw-r--r--horizon/locale/fr/LC_MESSAGES/djangojs.mobin419 -> 0 bytes
-rw-r--r--horizon/locale/fr/LC_MESSAGES/djangojs.po74
-rw-r--r--horizon/locale/hu/LC_MESSAGES/django.mobin7176 -> 0 bytes
-rw-r--r--horizon/locale/hu/LC_MESSAGES/django.po515
-rw-r--r--horizon/locale/it/LC_MESSAGES/django.mobin2915 -> 0 bytes
-rw-r--r--horizon/locale/it/LC_MESSAGES/django.po515
-rw-r--r--horizon/locale/it/LC_MESSAGES/djangojs.mobin420 -> 0 bytes
-rw-r--r--horizon/locale/it/LC_MESSAGES/djangojs.po74
-rw-r--r--horizon/locale/ja/LC_MESSAGES/django.mobin7551 -> 0 bytes
-rw-r--r--horizon/locale/ja/LC_MESSAGES/django.po511
-rw-r--r--horizon/locale/ja/LC_MESSAGES/djangojs.mobin413 -> 0 bytes
-rw-r--r--horizon/locale/ja/LC_MESSAGES/djangojs.po73
-rw-r--r--horizon/locale/ka_GE/LC_MESSAGES/django.mobin1960 -> 0 bytes
-rw-r--r--horizon/locale/ka_GE/LC_MESSAGES/django.po508
-rw-r--r--horizon/locale/ko_KR/LC_MESSAGES/django.mobin2871 -> 0 bytes
-rw-r--r--horizon/locale/ko_KR/LC_MESSAGES/django.po509
-rw-r--r--horizon/locale/ko_KR/LC_MESSAGES/djangojs.mobin378 -> 0 bytes
-rw-r--r--horizon/locale/ko_KR/LC_MESSAGES/djangojs.po73
-rw-r--r--horizon/locale/nl_NL/LC_MESSAGES/django.mobin2949 -> 0 bytes
-rw-r--r--horizon/locale/nl_NL/LC_MESSAGES/django.po514
-rw-r--r--horizon/locale/nl_NL/LC_MESSAGES/djangojs.mobin378 -> 0 bytes
-rw-r--r--horizon/locale/nl_NL/LC_MESSAGES/djangojs.po73
-rw-r--r--horizon/locale/pl/LC_MESSAGES/django.mobin572 -> 0 bytes
-rw-r--r--horizon/locale/pl/LC_MESSAGES/django.po530
-rw-r--r--horizon/locale/pl/LC_MESSAGES/djangojs.mobin478 -> 0 bytes
-rw-r--r--horizon/locale/pl/LC_MESSAGES/djangojs.po76
-rw-r--r--horizon/locale/pt/LC_MESSAGES/django.mobin4432 -> 0 bytes
-rw-r--r--horizon/locale/pt/LC_MESSAGES/django.po513
-rw-r--r--horizon/locale/pt/LC_MESSAGES/djangojs.mobin420 -> 0 bytes
-rw-r--r--horizon/locale/pt/LC_MESSAGES/djangojs.po74
-rw-r--r--horizon/locale/pt_BR/LC_MESSAGES/django.mobin6948 -> 0 bytes
-rw-r--r--horizon/locale/pt_BR/LC_MESSAGES/django.po518
-rw-r--r--horizon/locale/pt_BR/LC_MESSAGES/djangojs.mobin419 -> 0 bytes
-rw-r--r--horizon/locale/pt_BR/LC_MESSAGES/djangojs.po74
-rw-r--r--horizon/locale/ru/LC_MESSAGES/django.mobin7793 -> 0 bytes
-rw-r--r--horizon/locale/ru/LC_MESSAGES/django.po520
-rw-r--r--horizon/locale/ru/LC_MESSAGES/djangojs.mobin494 -> 0 bytes
-rw-r--r--horizon/locale/ru/LC_MESSAGES/djangojs.po75
-rw-r--r--horizon/locale/zh_CN/LC_MESSAGES/django.mobin5414 -> 0 bytes
-rw-r--r--horizon/locale/zh_CN/LC_MESSAGES/django.po516
-rw-r--r--horizon/locale/zh_CN/LC_MESSAGES/djangojs.mobin413 -> 0 bytes
-rw-r--r--horizon/locale/zh_CN/LC_MESSAGES/djangojs.po73
-rw-r--r--horizon/locale/zh_HK/LC_MESSAGES/django.mobin3782 -> 0 bytes
-rw-r--r--horizon/locale/zh_HK/LC_MESSAGES/django.po508
-rw-r--r--horizon/locale/zh_TW/LC_MESSAGES/django.mobin5052 -> 0 bytes
-rw-r--r--horizon/locale/zh_TW/LC_MESSAGES/django.po508
-rw-r--r--horizon/locale/zh_TW/LC_MESSAGES/djangojs.mobin413 -> 0 bytes
-rw-r--r--horizon/locale/zh_TW/LC_MESSAGES/djangojs.po73
-rw-r--r--horizon/management/__init__.py0
-rw-r--r--horizon/management/commands/__init__.py0
-rw-r--r--horizon/management/commands/startdash.py59
-rw-r--r--horizon/management/commands/startpanel.py97
-rw-r--r--horizon/messages.py83
-rw-r--r--horizon/middleware.py129
-rw-r--r--horizon/models.py23
-rw-r--r--horizon/site_urls.py47
-rw-r--r--horizon/static/bootstrap/js/bootstrap-datepicker.js470
-rw-r--r--horizon/static/bootstrap/js/bootstrap.js1720
-rw-r--r--horizon/static/bootstrap/js/bootstrap.min.js1
-rw-r--r--horizon/static/horizon/js/horizon.communication.js51
-rw-r--r--horizon/static/horizon/js/horizon.conf.js31
-rw-r--r--horizon/static/horizon/js/horizon.cookies.js23
-rw-r--r--horizon/static/horizon/js/horizon.d3piechart.js102
-rw-r--r--horizon/static/horizon/js/horizon.forms.js190
-rw-r--r--horizon/static/horizon/js/horizon.heattop.js275
-rw-r--r--horizon/static/horizon/js/horizon.instances.js226
-rw-r--r--horizon/static/horizon/js/horizon.js35
-rw-r--r--horizon/static/horizon/js/horizon.messages.js65
-rw-r--r--horizon/static/horizon/js/horizon.modals.js223
-rw-r--r--horizon/static/horizon/js/horizon.networktopology.js280
-rw-r--r--horizon/static/horizon/js/horizon.projects.js474
-rw-r--r--horizon/static/horizon/js/horizon.quota.js333
-rw-r--r--horizon/static/horizon/js/horizon.tables.js392
-rw-r--r--horizon/static/horizon/js/horizon.tabs.js84
-rw-r--r--horizon/static/horizon/js/horizon.templates.js17
-rw-r--r--horizon/static/horizon/js/horizon.users.js31
-rw-r--r--horizon/static/horizon/js/horizon.utils.js44
-rw-r--r--horizon/static/horizon/lib/d3.v3.min.js5
-rw-r--r--horizon/static/horizon/lib/hogan-2.0.0.js576
-rwxr-xr-xhorizon/static/horizon/lib/jquery/jquery-ui-1.9.2.custom.min.js6
-rw-r--r--horizon/static/horizon/lib/jquery/jquery.cookie.js47
-rw-r--r--horizon/static/horizon/lib/jquery/jquery.min.js4
-rw-r--r--horizon/static/horizon/lib/jquery/jquery.quicksearch.js150
-rw-r--r--horizon/static/horizon/lib/jquery/jquery.table-sorter.js1031
-rw-r--r--horizon/static/horizon/lib/json2.js487
-rw-r--r--horizon/static/horizon/lib/qunit/qunit.css238
-rw-r--r--horizon/static/horizon/lib/qunit/qunit.js1865
-rw-r--r--horizon/static/horizon/lib/spin.jquery.js17
-rw-r--r--horizon/static/horizon/lib/spin.js2
-rw-r--r--horizon/static/horizon/lib/underscore/underscore-min.js32
-rw-r--r--horizon/static/horizon/tests/messages.js38
-rw-r--r--horizon/static/horizon/tests/modals.js22
-rw-r--r--horizon/static/horizon/tests/tables.js49
-rw-r--r--horizon/static/horizon/tests/templates.js7
-rw-r--r--horizon/tables/__init__.py44
-rw-r--r--horizon/tables/actions.py625
-rw-r--r--horizon/tables/base.py1396
-rw-r--r--horizon/tables/views.py261
-rw-r--r--horizon/tabs/__init__.py27
-rw-r--r--horizon/tabs/base.py459
-rw-r--r--horizon/tabs/views.py141
-rw-r--r--horizon/templates/_header.html9
-rw-r--r--horizon/templates/_stylesheets.html1
-rw-r--r--horizon/templates/auth/_login.html29
-rw-r--r--horizon/templates/auth/login.html10
-rw-r--r--horizon/templates/base.html38
-rw-r--r--horizon/templates/horizon/_conf.html21
-rw-r--r--horizon/templates/horizon/_messages.html29
-rw-r--r--horizon/templates/horizon/_nav_list.html13
-rw-r--r--horizon/templates/horizon/_scripts.html52
-rw-r--r--horizon/templates/horizon/_subnav_list.html16
-rw-r--r--horizon/templates/horizon/client_side/_alert_message.html21
-rw-r--r--horizon/templates/horizon/client_side/_loading.html12
-rw-r--r--horizon/templates/horizon/client_side/_modal.html22
-rw-r--r--horizon/templates/horizon/client_side/_modal_chart.html19
-rw-r--r--horizon/templates/horizon/client_side/_project_user.html26
-rw-r--r--horizon/templates/horizon/client_side/_script_loader.html20
-rw-r--r--horizon/templates/horizon/client_side/_table_row.html10
-rw-r--r--horizon/templates/horizon/client_side/template.html1
-rw-r--r--horizon/templates/horizon/client_side/templates.html6
-rw-r--r--horizon/templates/horizon/common/_breadcrumb.html20
-rw-r--r--horizon/templates/horizon/common/_data_table.html78
-rw-r--r--horizon/templates/horizon/common/_data_table_row.html3
-rw-r--r--horizon/templates/horizon/common/_data_table_row_action.html5
-rw-r--r--horizon/templates/horizon/common/_data_table_row_actions.html30
-rw-r--r--horizon/templates/horizon/common/_data_table_table_actions.html28
-rw-r--r--horizon/templates/horizon/common/_detail_table.html1
-rw-r--r--horizon/templates/horizon/common/_domain_page_header.html11
-rw-r--r--horizon/templates/horizon/common/_form_fields.html22
-rw-r--r--horizon/templates/horizon/common/_limit_summary.html39
-rw-r--r--horizon/templates/horizon/common/_modal.html10
-rw-r--r--horizon/templates/horizon/common/_modal_form.html24
-rw-r--r--horizon/templates/horizon/common/_modal_form_add_members.html41
-rw-r--r--horizon/templates/horizon/common/_page_header.html6
-rw-r--r--horizon/templates/horizon/common/_region_selector.html16
-rw-r--r--horizon/templates/horizon/common/_resource_browser.html13
-rw-r--r--horizon/templates/horizon/common/_sidebar.html54
-rw-r--r--horizon/templates/horizon/common/_sidebar_module.html10
-rw-r--r--horizon/templates/horizon/common/_tab_group.html23
-rw-r--r--horizon/templates/horizon/common/_usage_summary.html20
-rw-r--r--horizon/templates/horizon/common/_workflow.html43
-rw-r--r--horizon/templates/horizon/common/_workflow_base.html11
-rw-r--r--horizon/templates/horizon/common/_workflow_step.html13
-rw-r--r--horizon/templates/horizon/common/_workflow_step_update_members.html50
-rw-r--r--horizon/templates/horizon/qunit.html73
-rw-r--r--horizon/templates/splash.html17
-rw-r--r--horizon/templatetags/__init__.py0
-rw-r--r--horizon/templatetags/branding.py63
-rw-r--r--horizon/templatetags/horizon.py128
-rw-r--r--horizon/templatetags/parse_date.py54
-rw-r--r--horizon/templatetags/sizeformat.py77
-rw-r--r--horizon/templatetags/truncate_filter.py35
-rw-r--r--horizon/test/__init__.py0
-rw-r--r--horizon/test/customization/__init__.py0
-rw-r--r--horizon/test/customization/cust_test1.py15
-rw-r--r--horizon/test/customization/cust_test2.py9
-rw-r--r--horizon/test/helpers.py184
-rw-r--r--horizon/test/settings.py180
-rw-r--r--horizon/test/templates/404.html0
-rw-r--r--horizon/test/templates/_tab.html1
-rw-r--r--horizon/test/templates/base-sidebar.html0
-rw-r--r--horizon/test/templates/registration/login.html0
-rw-r--r--horizon/test/templates/tab_group.html1
-rw-r--r--horizon/test/templates/workflow.html1
-rw-r--r--horizon/test/test_dashboards/__init__.py0
-rw-r--r--horizon/test/test_dashboards/cats/__init__.py0
-rw-r--r--horizon/test/test_dashboards/cats/dashboard.py25
-rw-r--r--horizon/test/test_dashboards/cats/kittens/__init__.py0
-rw-r--r--horizon/test/test_dashboards/cats/kittens/models.py3
-rw-r--r--horizon/test/test_dashboards/cats/kittens/panel.py14
-rw-r--r--horizon/test/test_dashboards/cats/kittens/templates/kittens/index.html12
-rw-r--r--horizon/test/test_dashboards/cats/kittens/urls.py8
-rw-r--r--horizon/test/test_dashboards/cats/kittens/views.py10
-rw-r--r--horizon/test/test_dashboards/cats/models.py3
-rw-r--r--horizon/test/test_dashboards/cats/static/cats/css/cats.css1
-rw-r--r--horizon/test/test_dashboards/cats/static/cats/js/cats.js1
-rw-r--r--horizon/test/test_dashboards/cats/templates/cats/base.html11
-rw-r--r--horizon/test/test_dashboards/cats/tigers/__init__.py0
-rw-r--r--horizon/test/test_dashboards/cats/tigers/models.py3
-rw-r--r--horizon/test/test_dashboards/cats/tigers/panel.py14
-rw-r--r--horizon/test/test_dashboards/cats/tigers/templates/tigers/index.html12
-rw-r--r--horizon/test/test_dashboards/cats/tigers/urls.py8
-rw-r--r--horizon/test/test_dashboards/cats/tigers/views.py10
-rw-r--r--horizon/test/test_dashboards/dogs/__init__.py0
-rw-r--r--horizon/test/test_dashboards/dogs/dashboard.py13
-rw-r--r--horizon/test/test_dashboards/dogs/models.py3
-rw-r--r--horizon/test/test_dashboards/dogs/puppies/__init__.py0
-rw-r--r--horizon/test/test_dashboards/dogs/puppies/models.py3
-rw-r--r--horizon/test/test_dashboards/dogs/puppies/panel.py13
-rw-r--r--horizon/test/test_dashboards/dogs/puppies/templates/puppies/index.html12
-rw-r--r--horizon/test/test_dashboards/dogs/puppies/urls.py8
-rw-r--r--horizon/test/test_dashboards/dogs/puppies/views.py10
-rw-r--r--horizon/test/test_dashboards/dogs/static/dogs/css/dogs.css1
-rw-r--r--horizon/test/test_dashboards/dogs/static/dogs/js/dogs.js1
-rw-r--r--horizon/test/test_dashboards/dogs/templates/dogs/base.html11
-rw-r--r--horizon/test/tests/__init__.py0
-rw-r--r--horizon/test/tests/base.py390
-rw-r--r--horizon/test/tests/messages.py56
-rw-r--r--horizon/test/tests/middleware.py34
-rw-r--r--horizon/test/tests/selenium.py31
-rw-r--r--horizon/test/tests/tables.py755
-rw-r--r--horizon/test/tests/tabs.py307
-rw-r--r--horizon/test/tests/templatetags.py50
-rw-r--r--horizon/test/tests/utils.py196
-rw-r--r--horizon/test/tests/workflows.py266
-rw-r--r--horizon/test/urls.py45
-rw-r--r--horizon/utils/__init__.py0
-rw-r--r--horizon/utils/fields.py130
-rw-r--r--horizon/utils/filters.py38
-rw-r--r--horizon/utils/functions.py17
-rw-r--r--horizon/utils/html.py56
-rw-r--r--horizon/utils/memoized.py50
-rw-r--r--horizon/utils/secret_key.py67
-rw-r--r--horizon/utils/validators.py38
-rw-r--r--horizon/version.py19
-rw-r--r--horizon/views.py53
-rw-r--r--horizon/workflows/__init__.py13
-rw-r--r--horizon/workflows/base.py934
-rw-r--r--horizon/workflows/views.py158
-rw-r--r--openstack-common.conf9
-rw-r--r--openstack_dashboard/__init__.py0
-rw-r--r--openstack_dashboard/api/__init__.py58
-rw-r--r--openstack_dashboard/api/base.py263
-rw-r--r--openstack_dashboard/api/cinder.py159
-rw-r--r--openstack_dashboard/api/glance.py104
-rw-r--r--openstack_dashboard/api/heat.py86
-rw-r--r--openstack_dashboard/api/keystone.py545
-rw-r--r--openstack_dashboard/api/lbaas.py321
-rw-r--r--openstack_dashboard/api/network.py129
-rw-r--r--openstack_dashboard/api/network_base.py216
-rw-r--r--openstack_dashboard/api/neutron.py605
-rw-r--r--openstack_dashboard/api/nova.py651
-rw-r--r--openstack_dashboard/api/swift.py241
-rw-r--r--openstack_dashboard/context_processors.py63
-rw-r--r--openstack_dashboard/dashboards/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/aggregates/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/aggregates/panel.py29
-rw-r--r--openstack_dashboard/dashboards/admin/aggregates/tables.py54
-rw-r--r--openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/_aggregate_hosts.html5
-rw-r--r--openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/_aggregate_metadata.html5
-rw-r--r--openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/aggregates/tests.py34
-rw-r--r--openstack_dashboard/dashboards/admin/aggregates/urls.py27
-rw-r--r--openstack_dashboard/dashboards/admin/aggregates/views.py42
-rw-r--r--openstack_dashboard/dashboards/admin/dashboard.py43
-rw-r--r--openstack_dashboard/dashboards/admin/domains/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/domains/constants.py23
-rw-r--r--openstack_dashboard/dashboards/admin/domains/panel.py37
-rw-r--r--openstack_dashboard/dashboards/admin/domains/tables.py149
-rw-r--r--openstack_dashboard/dashboards/admin/domains/templates/domains/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/domains/tests.py228
-rw-r--r--openstack_dashboard/dashboards/admin/domains/urls.py30
-rw-r--r--openstack_dashboard/dashboards/admin/domains/views.py82
-rw-r--r--openstack_dashboard/dashboards/admin/domains/workflows.py127
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/extras/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/extras/forms.py67
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/extras/tables.py74
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/extras/tests.py62
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/extras/urls.py33
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/extras/views.py98
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/forms.py144
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/panel.py33
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/tables.py68
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/templates/flavors/_create.html26
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/templates/flavors/_edit.html27
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/templates/flavors/create.html11
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/templates/flavors/edit.html11
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_create.html28
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_edit.html28
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_index.html15
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/create.html12
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/edit.html12
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/index.html12
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/templates/flavors/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/tests.py234
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/urls.py36
-rw-r--r--openstack_dashboard/dashboards/admin/flavors/views.py85
-rw-r--r--openstack_dashboard/dashboards/admin/groups/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/groups/constants.py11
-rw-r--r--openstack_dashboard/dashboards/admin/groups/forms.py77
-rw-r--r--openstack_dashboard/dashboards/admin/groups/panel.py31
-rw-r--r--openstack_dashboard/dashboards/admin/groups/tables.py212
-rw-r--r--openstack_dashboard/dashboards/admin/groups/templates/groups/_add_non_member.html9
-rw-r--r--openstack_dashboard/dashboards/admin/groups/templates/groups/_create.html25
-rw-r--r--openstack_dashboard/dashboards/admin/groups/templates/groups/_update.html25
-rw-r--r--openstack_dashboard/dashboards/admin/groups/templates/groups/add_non_member.html7
-rw-r--r--openstack_dashboard/dashboards/admin/groups/templates/groups/create.html11
-rw-r--r--openstack_dashboard/dashboards/admin/groups/templates/groups/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/groups/templates/groups/manage.html11
-rw-r--r--openstack_dashboard/dashboards/admin/groups/templates/groups/update.html11
-rw-r--r--openstack_dashboard/dashboards/admin/groups/tests.py237
-rw-r--r--openstack_dashboard/dashboards/admin/groups/urls.py36
-rw-r--r--openstack_dashboard/dashboards/admin/groups/views.py171
-rw-r--r--openstack_dashboard/dashboards/admin/hypervisors/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/hypervisors/panel.py29
-rw-r--r--openstack_dashboard/dashboards/admin/hypervisors/tables.py75
-rw-r--r--openstack_dashboard/dashboards/admin/hypervisors/templates/hypervisors/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/hypervisors/tests.py34
-rw-r--r--openstack_dashboard/dashboards/admin/hypervisors/urls.py27
-rw-r--r--openstack_dashboard/dashboards/admin/hypervisors/views.py42
-rw-r--r--openstack_dashboard/dashboards/admin/images/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/images/forms.py30
-rw-r--r--openstack_dashboard/dashboards/admin/images/panel.py33
-rw-r--r--openstack_dashboard/dashboards/admin/images/tables.py59
-rw-r--r--openstack_dashboard/dashboards/admin/images/templates/images/_create.html35
-rw-r--r--openstack_dashboard/dashboards/admin/images/templates/images/_update.html26
-rw-r--r--openstack_dashboard/dashboards/admin/images/templates/images/create.html11
-rw-r--r--openstack_dashboard/dashboards/admin/images/templates/images/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/images/templates/images/update.html12
-rw-r--r--openstack_dashboard/dashboards/admin/images/tests.py106
-rw-r--r--openstack_dashboard/dashboards/admin/images/urls.py35
-rw-r--r--openstack_dashboard/dashboards/admin/images/views.py80
-rw-r--r--openstack_dashboard/dashboards/admin/info/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/info/panel.py33
-rw-r--r--openstack_dashboard/dashboards/admin/info/tables.py121
-rw-r--r--openstack_dashboard/dashboards/admin/info/tabs.py85
-rw-r--r--openstack_dashboard/dashboards/admin/info/templates/info/index.html15
-rw-r--r--openstack_dashboard/dashboards/admin/info/tests.py71
-rw-r--r--openstack_dashboard/dashboards/admin/info/urls.py28
-rw-r--r--openstack_dashboard/dashboards/admin/info/views.py33
-rw-r--r--openstack_dashboard/dashboards/admin/instances/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/instances/panel.py34
-rw-r--r--openstack_dashboard/dashboards/admin/instances/tables.py170
-rw-r--r--openstack_dashboard/dashboards/admin/instances/templates/instances/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/instances/tests.py208
-rw-r--r--openstack_dashboard/dashboards/admin/instances/urls.py41
-rw-r--r--openstack_dashboard/dashboards/admin/instances/views.py121
-rw-r--r--openstack_dashboard/dashboards/admin/models.py23
-rw-r--r--openstack_dashboard/dashboards/admin/networks/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/networks/forms.py102
-rw-r--r--openstack_dashboard/dashboards/admin/networks/panel.py29
-rw-r--r--openstack_dashboard/dashboards/admin/networks/ports/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/networks/ports/forms.py104
-rw-r--r--openstack_dashboard/dashboards/admin/networks/ports/tables.py87
-rw-r--r--openstack_dashboard/dashboards/admin/networks/ports/tabs.py49
-rw-r--r--openstack_dashboard/dashboards/admin/networks/ports/urls.py29
-rw-r--r--openstack_dashboard/dashboards/admin/networks/ports/views.py75
-rw-r--r--openstack_dashboard/dashboards/admin/networks/subnets/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/networks/subnets/tables.py83
-rw-r--r--openstack_dashboard/dashboards/admin/networks/subnets/urls.py30
-rw-r--r--openstack_dashboard/dashboards/admin/networks/subnets/views.py36
-rw-r--r--openstack_dashboard/dashboards/admin/networks/subnets/workflows.py60
-rw-r--r--openstack_dashboard/dashboards/admin/networks/tables.py82
-rw-r--r--openstack_dashboard/dashboards/admin/networks/templates/networks/_create.html26
-rw-r--r--openstack_dashboard/dashboards/admin/networks/templates/networks/_update.html25
-rw-r--r--openstack_dashboard/dashboards/admin/networks/templates/networks/create.html11
-rw-r--r--openstack_dashboard/dashboards/admin/networks/templates/networks/index.html21
-rw-r--r--openstack_dashboard/dashboards/admin/networks/templates/networks/ports/_create.html26
-rw-r--r--openstack_dashboard/dashboards/admin/networks/templates/networks/ports/_update.html30
-rw-r--r--openstack_dashboard/dashboards/admin/networks/templates/networks/ports/create.html11
-rw-r--r--openstack_dashboard/dashboards/admin/networks/templates/networks/ports/update.html11
-rw-r--r--openstack_dashboard/dashboards/admin/networks/templates/networks/subnets/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/networks/templates/networks/update.html11
-rw-r--r--openstack_dashboard/dashboards/admin/networks/tests.py822
-rw-r--r--openstack_dashboard/dashboards/admin/networks/urls.py59
-rw-r--r--openstack_dashboard/dashboards/admin/networks/views.py146
-rw-r--r--openstack_dashboard/dashboards/admin/overview/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/overview/panel.py34
-rw-r--r--openstack_dashboard/dashboards/admin/overview/templates/overview/usage.csv6
-rw-r--r--openstack_dashboard/dashboards/admin/overview/templates/overview/usage.html22
-rw-r--r--openstack_dashboard/dashboards/admin/overview/tests.py106
-rw-r--r--openstack_dashboard/dashboards/admin/overview/urls.py30
-rw-r--r--openstack_dashboard/dashboards/admin/overview/views.py73
-rw-r--r--openstack_dashboard/dashboards/admin/projects/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/projects/forms.py33
-rw-r--r--openstack_dashboard/dashboards/admin/projects/panel.py33
-rw-r--r--openstack_dashboard/dashboards/admin/projects/tables.py168
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/_add_user.html26
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/_create.html26
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/_create_user.html26
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/_quotas.html25
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/_update.html26
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/_update_members.html39
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/add_user.html11
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/create_user.html12
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/quotas.html11
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/usage.html12
-rw-r--r--openstack_dashboard/dashboards/admin/projects/templates/projects/users.html18
-rw-r--r--openstack_dashboard/dashboards/admin/projects/tests.py1069
-rw-r--r--openstack_dashboard/dashboards/admin/projects/urls.py43
-rw-r--r--openstack_dashboard/dashboards/admin/projects/views.py213
-rw-r--r--openstack_dashboard/dashboards/admin/projects/workflows.py428
-rw-r--r--openstack_dashboard/dashboards/admin/roles/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/roles/forms.py48
-rw-r--r--openstack_dashboard/dashboards/admin/roles/panel.py30
-rw-r--r--openstack_dashboard/dashboards/admin/roles/tables.py76
-rw-r--r--openstack_dashboard/dashboards/admin/roles/templates/roles/_create.html25
-rw-r--r--openstack_dashboard/dashboards/admin/roles/templates/roles/_update.html25
-rw-r--r--openstack_dashboard/dashboards/admin/roles/templates/roles/create.html12
-rw-r--r--openstack_dashboard/dashboards/admin/roles/templates/roles/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/roles/templates/roles/update.html12
-rw-r--r--openstack_dashboard/dashboards/admin/roles/tests.py113
-rw-r--r--openstack_dashboard/dashboards/admin/roles/urls.py27
-rw-r--r--openstack_dashboard/dashboards/admin/roles/views.py77
-rw-r--r--openstack_dashboard/dashboards/admin/routers/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/routers/panel.py29
-rw-r--r--openstack_dashboard/dashboards/admin/routers/ports/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/routers/ports/tables.py47
-rw-r--r--openstack_dashboard/dashboards/admin/routers/ports/tabs.py31
-rw-r--r--openstack_dashboard/dashboards/admin/routers/ports/urls.py25
-rw-r--r--openstack_dashboard/dashboards/admin/routers/ports/views.py30
-rw-r--r--openstack_dashboard/dashboards/admin/routers/tables.py75
-rw-r--r--openstack_dashboard/dashboards/admin/routers/tabs.py28
-rw-r--r--openstack_dashboard/dashboards/admin/routers/templates/routers/_detail_overview.html22
-rw-r--r--openstack_dashboard/dashboards/admin/routers/templates/routers/detail.html15
-rw-r--r--openstack_dashboard/dashboards/admin/routers/templates/routers/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/routers/tests.py63
-rw-r--r--openstack_dashboard/dashboards/admin/routers/urls.py29
-rw-r--r--openstack_dashboard/dashboards/admin/routers/views.py72
-rw-r--r--openstack_dashboard/dashboards/admin/users/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/users/forms.py168
-rw-r--r--openstack_dashboard/dashboards/admin/users/panel.py33
-rw-r--r--openstack_dashboard/dashboards/admin/users/tables.py122
-rw-r--r--openstack_dashboard/dashboards/admin/users/templates/users/_create.html35
-rw-r--r--openstack_dashboard/dashboards/admin/users/templates/users/_update.html35
-rw-r--r--openstack_dashboard/dashboards/admin/users/templates/users/create.html12
-rw-r--r--openstack_dashboard/dashboards/admin/users/templates/users/index.html11
-rw-r--r--openstack_dashboard/dashboards/admin/users/templates/users/update.html12
-rw-r--r--openstack_dashboard/dashboards/admin/users/tests.py462
-rw-r--r--openstack_dashboard/dashboards/admin/users/urls.py31
-rw-r--r--openstack_dashboard/dashboards/admin/users/views.py117
-rw-r--r--openstack_dashboard/dashboards/admin/volumes/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/admin/volumes/forms.py44
-rw-r--r--openstack_dashboard/dashboards/admin/volumes/panel.py14
-rw-r--r--openstack_dashboard/dashboards/admin/volumes/tables.py69
-rw-r--r--openstack_dashboard/dashboards/admin/volumes/templates/volumes/_create_volume_type.html30
-rw-r--r--openstack_dashboard/dashboards/admin/volumes/templates/volumes/create_volume_type.html11
-rw-r--r--openstack_dashboard/dashboards/admin/volumes/templates/volumes/detail.html15
-rw-r--r--openstack_dashboard/dashboards/admin/volumes/templates/volumes/index.html17
-rw-r--r--openstack_dashboard/dashboards/admin/volumes/tests.py94
-rw-r--r--openstack_dashboard/dashboards/admin/volumes/urls.py13
-rw-r--r--openstack_dashboard/dashboards/admin/volumes/views.py89
-rw-r--r--openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.capacity.js163
-rw-r--r--openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3circleschart.js279
-rw-r--r--openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3linechart.js200
-rw-r--r--openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3singlebarchart.js474
-rw-r--r--openstack_dashboard/dashboards/infrastructure/templates/infrastructure/_scripts.html7
-rw-r--r--openstack_dashboard/dashboards/project/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/api_access/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/api_access/tables.py59
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/api_access/tests.py51
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/api_access/urls.py33
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/api_access/views.py135
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/floating_ips/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/floating_ips/forms.py48
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/floating_ips/tables.py134
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/floating_ips/tests.py177
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/floating_ips/urls.py33
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/floating_ips/views.py72
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/floating_ips/workflows.py143
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/keypairs/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/keypairs/forms.py66
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/keypairs/tables.py62
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/keypairs/tests.py144
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/keypairs/urls.py41
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/keypairs/views.py88
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/panel.py30
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/security_groups/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/security_groups/forms.py354
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/security_groups/tables.py168
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/security_groups/tests.py664
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/security_groups/urls.py40
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/security_groups/views.py114
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/tabs.py132
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/ec2rc.sh.template15
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/openrc.sh.template24
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html44
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html7
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/index.html15
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html26
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html26
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html12
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html22
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html12
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html29
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html26
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html12
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html11
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html11
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/tests.py102
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/urls.py44
-rw-r--r--openstack_dashboard/dashboards/project/access_and_security/views.py34
-rw-r--r--openstack_dashboard/dashboards/project/containers/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/containers/browsers.py36
-rw-r--r--openstack_dashboard/dashboards/project/containers/forms.py153
-rw-r--r--openstack_dashboard/dashboards/project/containers/panel.py33
-rw-r--r--openstack_dashboard/dashboards/project/containers/tables.py241
-rw-r--r--openstack_dashboard/dashboards/project/containers/templates/containers/_copy.html25
-rw-r--r--openstack_dashboard/dashboards/project/containers/templates/containers/_create.html25
-rw-r--r--openstack_dashboard/dashboards/project/containers/templates/containers/_upload.html27
-rw-r--r--openstack_dashboard/dashboards/project/containers/templates/containers/copy.html13
-rw-r--r--openstack_dashboard/dashboards/project/containers/templates/containers/create.html11
-rw-r--r--openstack_dashboard/dashboards/project/containers/templates/containers/index.html13
-rw-r--r--openstack_dashboard/dashboards/project/containers/templates/containers/upload.html15
-rw-r--r--openstack_dashboard/dashboards/project/containers/tests.py239
-rw-r--r--openstack_dashboard/dashboards/project/containers/urls.py55
-rw-r--r--openstack_dashboard/dashboards/project/containers/views.py228
-rw-r--r--openstack_dashboard/dashboards/project/dashboard.py62
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/images/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/images/forms.py223
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/images/tables.py229
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/images/tabs.py45
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/images/tests.py264
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/images/urls.py40
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/images/views.py91
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/panel.py30
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/forms.py57
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/tests.py98
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/urls.py32
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/views.py66
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html35
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html82
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html25
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html11
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html16
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html11
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html16
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html26
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html42
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html11
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html15
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/tests.py174
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/urls.py42
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/utils.py63
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/views.py84
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tables.py96
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tabs.py49
-rw-r--r--openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tests.py94
-rw-r--r--openstack_dashboard/dashboards/project/instances/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/instances/panel.py29
-rw-r--r--openstack_dashboard/dashboards/project/instances/tables.py575
-rw-r--r--openstack_dashboard/dashboards/project/instances/tabs.py110
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/_detail_console.html22
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/_detail_log.html18
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/_detail_overview.html111
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/_flavors_and_quotas.html50
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/_instance_ips.html10
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/_launch_customize_help.html3
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/_launch_details_help.html7
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/_launch_network_help.html3
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/_launch_volumes_help.html3
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/_update_networks.html46
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/detail.html15
-rw-r--r--openstack_dashboard/dashboards/project/instances/templates/instances/index.html11
-rw-r--r--openstack_dashboard/dashboards/project/instances/tests.py1740
-rw-r--r--openstack_dashboard/dashboards/project/instances/urls.py45
-rw-r--r--openstack_dashboard/dashboards/project/instances/views.py262
-rw-r--r--openstack_dashboard/dashboards/project/instances/workflows/__init__.py7
-rw-r--r--openstack_dashboard/dashboards/project/instances/workflows/create_instance.py546
-rw-r--r--openstack_dashboard/dashboards/project/instances/workflows/resize_instance.py111
-rw-r--r--openstack_dashboard/dashboards/project/instances/workflows/update_instance.py148
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/forms.py246
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/models.py3
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/panel.py21
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/tables.py243
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/tabs.py173
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html30
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_members_tab.html5
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html41
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_monitors_tab.html5
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html42
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_pools_tab.html5
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatemember.html25
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatemonitor.html25
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatepool.html25
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatevip.html25
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html48
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html15
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatemember.html11
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatemonitor.html11
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatepool.html11
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatevip.html11
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/tests.py794
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/urls.py77
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/views.py338
-rw-r--r--openstack_dashboard/dashboards/project/loadbalancers/workflows.py609
-rw-r--r--openstack_dashboard/dashboards/project/models.py23
-rw-r--r--openstack_dashboard/dashboards/project/network_topology/__init__.py19
-rw-r--r--openstack_dashboard/dashboards/project/network_topology/panel.py34
-rw-r--r--openstack_dashboard/dashboards/project/network_topology/templates/network_topology/index.html37
-rw-r--r--openstack_dashboard/dashboards/project/network_topology/urls.py35
-rw-r--r--openstack_dashboard/dashboards/project/network_topology/views.py143
-rw-r--r--openstack_dashboard/dashboards/project/networks/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/networks/forms.py59
-rw-r--r--openstack_dashboard/dashboards/project/networks/panel.py29
-rw-r--r--openstack_dashboard/dashboards/project/networks/ports/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/networks/ports/forms.py56
-rw-r--r--openstack_dashboard/dashboards/project/networks/ports/tables.py71
-rw-r--r--openstack_dashboard/dashboards/project/networks/ports/tabs.py49
-rw-r--r--openstack_dashboard/dashboards/project/networks/ports/urls.py30
-rw-r--r--openstack_dashboard/dashboards/project/networks/ports/views.py74
-rw-r--r--openstack_dashboard/dashboards/project/networks/subnets/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/networks/subnets/tables.py107
-rw-r--r--openstack_dashboard/dashboards/project/networks/subnets/tabs.py49
-rw-r--r--openstack_dashboard/dashboards/project/networks/subnets/urls.py30
-rw-r--r--openstack_dashboard/dashboards/project/networks/subnets/views.py106
-rw-r--r--openstack_dashboard/dashboards/project/networks/subnets/workflows.py196
-rw-r--r--openstack_dashboard/dashboards/project/networks/tables.py108
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/_create.html25
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/_detail_overview.html28
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/_network_ips.html10
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/_update.html25
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/detail.html18
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/index.html11
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/ports/_detail_overview.html44
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/ports/_port_ips.html7
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/ports/_update.html30
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/ports/detail.html15
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/ports/update.html11
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/subnets/_detail_overview.html50
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/subnets/detail.html15
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/subnets/index.html11
-rw-r--r--openstack_dashboard/dashboards/project/networks/templates/networks/update.html11
-rw-r--r--openstack_dashboard/dashboards/project/networks/tests.py1335
-rw-r--r--openstack_dashboard/dashboards/project/networks/urls.py52
-rw-r--r--openstack_dashboard/dashboards/project/networks/views.py148
-rw-r--r--openstack_dashboard/dashboards/project/networks/workflows.py370
-rw-r--r--openstack_dashboard/dashboards/project/overview/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/overview/panel.py33
-rw-r--r--openstack_dashboard/dashboards/project/overview/templates/overview/usage.csv7
-rw-r--r--openstack_dashboard/dashboards/project/overview/templates/overview/usage.html13
-rw-r--r--openstack_dashboard/dashboards/project/overview/tests.py154
-rw-r--r--openstack_dashboard/dashboards/project/overview/urls.py33
-rw-r--r--openstack_dashboard/dashboards/project/overview/views.py61
-rw-r--r--openstack_dashboard/dashboards/project/routers/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/routers/forms.py41
-rw-r--r--openstack_dashboard/dashboards/project/routers/panel.py29
-rw-r--r--openstack_dashboard/dashboards/project/routers/ports/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/routers/ports/forms.py191
-rw-r--r--openstack_dashboard/dashboards/project/routers/ports/tables.py98
-rw-r--r--openstack_dashboard/dashboards/project/routers/ports/tabs.py47
-rw-r--r--openstack_dashboard/dashboards/project/routers/ports/urls.py26
-rw-r--r--openstack_dashboard/dashboards/project/routers/ports/views.py105
-rw-r--r--openstack_dashboard/dashboards/project/routers/tables.py142
-rw-r--r--openstack_dashboard/dashboards/project/routers/tabs.py44
-rw-r--r--openstack_dashboard/dashboards/project/routers/templates/routers/_create.html22
-rw-r--r--openstack_dashboard/dashboards/project/routers/templates/routers/_detail_overview.html20
-rw-r--r--openstack_dashboard/dashboards/project/routers/templates/routers/create.html11
-rw-r--r--openstack_dashboard/dashboards/project/routers/templates/routers/detail.html15
-rw-r--r--openstack_dashboard/dashboards/project/routers/templates/routers/index.html11
-rw-r--r--openstack_dashboard/dashboards/project/routers/templates/routers/ports/_create.html31
-rw-r--r--openstack_dashboard/dashboards/project/routers/templates/routers/ports/_setgateway.html26
-rw-r--r--openstack_dashboard/dashboards/project/routers/templates/routers/ports/create.html11
-rw-r--r--openstack_dashboard/dashboards/project/routers/templates/routers/ports/setgateway.html11
-rw-r--r--openstack_dashboard/dashboards/project/routers/tests.py317
-rw-r--r--openstack_dashboard/dashboards/project/routers/urls.py40
-rw-r--r--openstack_dashboard/dashboards/project/routers/views.py146
-rw-r--r--openstack_dashboard/dashboards/project/stacks/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/stacks/api.py77
-rw-r--r--openstack_dashboard/dashboards/project/stacks/forms.py260
-rw-r--r--openstack_dashboard/dashboards/project/stacks/mappings.py145
-rw-r--r--openstack_dashboard/dashboards/project/stacks/panel.py27
-rw-r--r--openstack_dashboard/dashboards/project/stacks/sro.py31
-rw-r--r--openstack_dashboard/dashboards/project/stacks/tables.py179
-rw-r--r--openstack_dashboard/dashboards/project/stacks/tabs.py116
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/_create.html26
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_events.html3
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_overview.html66
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_resources.html3
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_topology.html9
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/_resource_info.html10
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/_resource_overview.html42
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/_select_template.html27
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/_stack_info.html16
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/create.html11
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/detail.html15
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/index.html13
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/resource.html15
-rw-r--r--openstack_dashboard/dashboards/project/stacks/templates/stacks/select_template.html11
-rw-r--r--openstack_dashboard/dashboards/project/stacks/tests.py156
-rw-r--r--openstack_dashboard/dashboards/project/stacks/urls.py38
-rw-r--r--openstack_dashboard/dashboards/project/stacks/views.py169
-rw-r--r--openstack_dashboard/dashboards/project/volumes/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/project/volumes/forms.py353
-rw-r--r--openstack_dashboard/dashboards/project/volumes/panel.py30
-rw-r--r--openstack_dashboard/dashboards/project/volumes/tables.py250
-rw-r--r--openstack_dashboard/dashboards/project/volumes/tabs.py49
-rw-r--r--openstack_dashboard/dashboards/project/volumes/templates/volumes/_attach.html26
-rw-r--r--openstack_dashboard/dashboards/project/volumes/templates/volumes/_create.html26
-rw-r--r--openstack_dashboard/dashboards/project/volumes/templates/volumes/_create_snapshot.html25
-rw-r--r--openstack_dashboard/dashboards/project/volumes/templates/volumes/_detail_overview.html61
-rw-r--r--openstack_dashboard/dashboards/project/volumes/templates/volumes/_limits.html34
-rw-r--r--openstack_dashboard/dashboards/project/volumes/templates/volumes/attach.html11
-rw-r--r--openstack_dashboard/dashboards/project/volumes/templates/volumes/create.html11
-rw-r--r--openstack_dashboard/dashboards/project/volumes/templates/volumes/create_snapshot.html11
-rw-r--r--openstack_dashboard/dashboards/project/volumes/templates/volumes/detail.html15
-rw-r--r--openstack_dashboard/dashboards/project/volumes/templates/volumes/index.html11
-rw-r--r--openstack_dashboard/dashboards/project/volumes/tests.py782
-rw-r--r--openstack_dashboard/dashboards/project/volumes/urls.py41
-rw-r--r--openstack_dashboard/dashboards/project/volumes/views.py209
-rw-r--r--openstack_dashboard/dashboards/settings/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/settings/dashboard.py31
-rw-r--r--openstack_dashboard/dashboards/settings/models.py23
-rw-r--r--openstack_dashboard/dashboards/settings/password/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/settings/password/forms.py68
-rw-r--r--openstack_dashboard/dashboards/settings/password/panel.py29
-rw-r--r--openstack_dashboard/dashboards/settings/password/templates/password/_change.html27
-rw-r--r--openstack_dashboard/dashboards/settings/password/templates/password/change.html11
-rw-r--r--openstack_dashboard/dashboards/settings/password/tests.py57
-rw-r--r--openstack_dashboard/dashboards/settings/password/urls.py24
-rw-r--r--openstack_dashboard/dashboards/settings/password/views.py26
-rw-r--r--openstack_dashboard/dashboards/settings/user/__init__.py0
-rw-r--r--openstack_dashboard/dashboards/settings/user/forms.py85
-rw-r--r--openstack_dashboard/dashboards/settings/user/panel.py29
-rw-r--r--openstack_dashboard/dashboards/settings/user/templates/user/_settings.html27
-rw-r--r--openstack_dashboard/dashboards/settings/user/templates/user/settings.html11
-rw-r--r--openstack_dashboard/dashboards/settings/user/tests.py33
-rw-r--r--openstack_dashboard/dashboards/settings/user/urls.py24
-rw-r--r--openstack_dashboard/dashboards/settings/user/views.py35
-rw-r--r--openstack_dashboard/exceptions.py71
-rw-r--r--openstack_dashboard/local/__init__.py0
-rw-r--r--openstack_dashboard/local/local_settings.py.example367
-rw-r--r--openstack_dashboard/locale/bg_BG/LC_MESSAGES/django.mobin1545 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/bg_BG/LC_MESSAGES/django.po4710
-rw-r--r--openstack_dashboard/locale/ca/LC_MESSAGES/django.mobin19571 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/ca/LC_MESSAGES/django.po4710
-rw-r--r--openstack_dashboard/locale/cs/LC_MESSAGES/django.mobin76251 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/cs/LC_MESSAGES/django.po4713
-rw-r--r--openstack_dashboard/locale/en/LC_MESSAGES/django.mobin1311 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/en/LC_MESSAGES/django.po4712
-rw-r--r--openstack_dashboard/locale/en_GB/LC_MESSAGES/django.mobin10625 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/en_GB/LC_MESSAGES/django.po4711
-rw-r--r--openstack_dashboard/locale/es/LC_MESSAGES/django.mobin73920 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/es/LC_MESSAGES/django.po4713
-rw-r--r--openstack_dashboard/locale/fi_FI/LC_MESSAGES/django.mobin77018 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/fi_FI/LC_MESSAGES/django.po4710
-rw-r--r--openstack_dashboard/locale/fr/LC_MESSAGES/django.mobin1735 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/fr/LC_MESSAGES/django.po4710
-rw-r--r--openstack_dashboard/locale/hu/LC_MESSAGES/django.mobin48580 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/hu/LC_MESSAGES/django.po4711
-rw-r--r--openstack_dashboard/locale/it/LC_MESSAGES/django.mobin23004 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/it/LC_MESSAGES/django.po4885
-rw-r--r--openstack_dashboard/locale/ja/LC_MESSAGES/django.mobin90772 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/ja/LC_MESSAGES/django.po4713
-rw-r--r--openstack_dashboard/locale/ka_GE/LC_MESSAGES/django.mobin19656 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/ka_GE/LC_MESSAGES/django.po4712
-rw-r--r--openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.mobin4702 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.po4711
-rw-r--r--openstack_dashboard/locale/nl_NL/LC_MESSAGES/django.mobin1328 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/nl_NL/LC_MESSAGES/django.po4710
-rw-r--r--openstack_dashboard/locale/pl/LC_MESSAGES/django.mobin757 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/pl/LC_MESSAGES/django.po5042
-rw-r--r--openstack_dashboard/locale/pt/LC_MESSAGES/django.mobin1384 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/pt/LC_MESSAGES/django.po4710
-rw-r--r--openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.mobin24198 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.po4713
-rw-r--r--openstack_dashboard/locale/ru/LC_MESSAGES/django.mobin6726 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/ru/LC_MESSAGES/django.po4712
-rw-r--r--openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.mobin1565 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.po4712
-rw-r--r--openstack_dashboard/locale/zh_TW/LC_MESSAGES/django.mobin1556 -> 0 bytes
-rw-r--r--openstack_dashboard/locale/zh_TW/LC_MESSAGES/django.po4711
-rw-r--r--openstack_dashboard/openstack/__init__.py0
-rw-r--r--openstack_dashboard/openstack/common/__init__.py0
-rw-r--r--openstack_dashboard/openstack/common/config/__init__.py0
-rwxr-xr-xopenstack_dashboard/openstack/common/config/generator.py253
-rw-r--r--openstack_dashboard/openstack/common/context.py82
-rw-r--r--openstack_dashboard/openstack/common/eventlet_backdoor.py89
-rw-r--r--openstack_dashboard/openstack/common/excutils.py51
-rw-r--r--openstack_dashboard/openstack/common/gettextutils.py226
-rw-r--r--openstack_dashboard/openstack/common/importutils.py67
-rw-r--r--openstack_dashboard/openstack/common/jsonutils.py169
-rw-r--r--openstack_dashboard/openstack/common/local.py48
-rw-r--r--openstack_dashboard/openstack/common/log.py558
-rw-r--r--openstack_dashboard/openstack/common/loopingcall.py147
-rw-r--r--openstack_dashboard/openstack/common/network_utils.py69
-rw-r--r--openstack_dashboard/openstack/common/notifier/__init__.py14
-rw-r--r--openstack_dashboard/openstack/common/notifier/api.py182
-rw-r--r--openstack_dashboard/openstack/common/notifier/log_notifier.py37
-rw-r--r--openstack_dashboard/openstack/common/notifier/no_op_notifier.py19
-rw-r--r--openstack_dashboard/openstack/common/notifier/rpc_notifier.py46
-rw-r--r--openstack_dashboard/openstack/common/notifier/rpc_notifier2.py52
-rw-r--r--openstack_dashboard/openstack/common/notifier/test_notifier.py22
-rw-r--r--openstack_dashboard/openstack/common/rpc/__init__.py307
-rw-r--r--openstack_dashboard/openstack/common/rpc/amqp.py678
-rw-r--r--openstack_dashboard/openstack/common/rpc/common.py516
-rw-r--r--openstack_dashboard/openstack/common/rpc/dispatcher.py178
-rw-r--r--openstack_dashboard/openstack/common/rpc/impl_fake.py195
-rw-r--r--openstack_dashboard/openstack/common/rpc/impl_kombu.py839
-rw-r--r--openstack_dashboard/openstack/common/rpc/impl_qpid.py703
-rw-r--r--openstack_dashboard/openstack/common/rpc/impl_zmq.py848
-rw-r--r--openstack_dashboard/openstack/common/rpc/matchmaker.py348
-rw-r--r--openstack_dashboard/openstack/common/rpc/matchmaker_redis.py149
-rw-r--r--openstack_dashboard/openstack/common/rpc/matchmaker_ring.py114
-rw-r--r--openstack_dashboard/openstack/common/rpc/proxy.py221
-rw-r--r--openstack_dashboard/openstack/common/rpc/serializer.py52
-rw-r--r--openstack_dashboard/openstack/common/rpc/service.py76
-rwxr-xr-xopenstack_dashboard/openstack/common/rpc/zmq_receiver.py41
-rw-r--r--openstack_dashboard/openstack/common/service.py333
-rw-r--r--openstack_dashboard/openstack/common/threadgroup.py121
-rw-r--r--openstack_dashboard/openstack/common/timeutils.py187
-rw-r--r--openstack_dashboard/openstack/common/uuidutils.py39
-rw-r--r--openstack_dashboard/settings.py207
-rw-r--r--openstack_dashboard/static/bootstrap/img/glyphicons-halflings-white.pngbin4352 -> 0 bytes
-rw-r--r--openstack_dashboard/static/bootstrap/img/glyphicons-halflings.pngbin4352 -> 0 bytes
-rw-r--r--openstack_dashboard/static/bootstrap/less/accordion.less28
-rw-r--r--openstack_dashboard/static/bootstrap/less/alerts.less70
-rw-r--r--openstack_dashboard/static/bootstrap/less/bootstrap.less62
-rw-r--r--openstack_dashboard/static/bootstrap/less/breadcrumbs.less22
-rw-r--r--openstack_dashboard/static/bootstrap/less/button-groups.less148
-rw-r--r--openstack_dashboard/static/bootstrap/less/buttons.less183
-rw-r--r--openstack_dashboard/static/bootstrap/less/carousel.less121
-rw-r--r--openstack_dashboard/static/bootstrap/less/close.less18
-rw-r--r--openstack_dashboard/static/bootstrap/less/code.less57
-rw-r--r--openstack_dashboard/static/bootstrap/less/component-animations.less18
-rw-r--r--openstack_dashboard/static/bootstrap/less/datepicker.less183
-rw-r--r--openstack_dashboard/static/bootstrap/less/dropdowns.less130
-rw-r--r--openstack_dashboard/static/bootstrap/less/forms.less522
-rw-r--r--openstack_dashboard/static/bootstrap/less/grid.less8
-rw-r--r--openstack_dashboard/static/bootstrap/less/hero-unit.less20
-rw-r--r--openstack_dashboard/static/bootstrap/less/labels.less32
-rw-r--r--openstack_dashboard/static/bootstrap/less/layouts.less17
-rw-r--r--openstack_dashboard/static/bootstrap/less/mixins.less590
-rw-r--r--openstack_dashboard/static/bootstrap/less/modals.less83
-rw-r--r--openstack_dashboard/static/bootstrap/less/navbar.less299
-rw-r--r--openstack_dashboard/static/bootstrap/less/navs.less353
-rw-r--r--openstack_dashboard/static/bootstrap/less/pager.less30
-rw-r--r--openstack_dashboard/static/bootstrap/less/pagination.less55
-rw-r--r--openstack_dashboard/static/bootstrap/less/popovers.less49
-rw-r--r--openstack_dashboard/static/bootstrap/less/progress-bars.less95
-rw-r--r--openstack_dashboard/static/bootstrap/less/reset.less126
-rw-r--r--openstack_dashboard/static/bootstrap/less/responsive.less327
-rw-r--r--openstack_dashboard/static/bootstrap/less/scaffolding.less29
-rw-r--r--openstack_dashboard/static/bootstrap/less/sprites.less158
-rw-r--r--openstack_dashboard/static/bootstrap/less/tables.less150
-rw-r--r--openstack_dashboard/static/bootstrap/less/thumbnails.less35
-rw-r--r--openstack_dashboard/static/bootstrap/less/tooltip.less35
-rw-r--r--openstack_dashboard/static/bootstrap/less/type.less222
-rw-r--r--openstack_dashboard/static/bootstrap/less/utilities.less23
-rw-r--r--openstack_dashboard/static/bootstrap/less/variables.less107
-rw-r--r--openstack_dashboard/static/bootstrap/less/wells.less17
-rw-r--r--openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.eotbin25687 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.svg244
-rw-r--r--openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.ttfbin56996 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.woffbin29432 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/action_required.pngbin1017 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/communication_flow.pngbin1662 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/db-gray.gifbin12495 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/db-gray.svg85
-rw-r--r--openstack_dashboard/static/dashboard/img/db-green.svg85
-rw-r--r--openstack_dashboard/static/dashboard/img/db-red.svg85
-rw-r--r--openstack_dashboard/static/dashboard/img/drag.pngbin1023 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/drop_arrow.pngbin2857 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/favicon.icobin1150 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/horizontal_loader.gifbin22580 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/lb-gray.gifbin8447 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/lb-gray.svg43
-rw-r--r--openstack_dashboard/static/dashboard/img/lb-green.svg43
-rw-r--r--openstack_dashboard/static/dashboard/img/lb-red.svg43
-rw-r--r--openstack_dashboard/static/dashboard/img/loading.gifbin2947 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/logo-splash.pngbin5093 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/logo.pngbin5093 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/right_droparrow.pngbin991 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/router.pngbin2321 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/search.pngbin431 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/server-gray.gifbin7416 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/server-gray.svg50
-rw-r--r--openstack_dashboard/static/dashboard/img/server-green.svg50
-rw-r--r--openstack_dashboard/static/dashboard/img/server-red.svg50
-rw-r--r--openstack_dashboard/static/dashboard/img/server.pngbin2050 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/stack-gray.gifbin14409 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/stack-gray.svg73
-rw-r--r--openstack_dashboard/static/dashboard/img/stack-green.svg82
-rw-r--r--openstack_dashboard/static/dashboard/img/stack-red.svg92
-rw-r--r--openstack_dashboard/static/dashboard/img/unknown-gray.gifbin10805 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/img/unknown-green.svg33
-rw-r--r--openstack_dashboard/static/dashboard/img/unknown-red.svg33
-rw-r--r--openstack_dashboard/static/dashboard/img/up_arrow.pngbin974 -> 0 bytes
-rw-r--r--openstack_dashboard/static/dashboard/less/horizon.less2122
-rw-r--r--openstack_dashboard/templates/403.html29
-rw-r--r--openstack_dashboard/templates/404.html28
-rw-r--r--openstack_dashboard/templates/500.html82
-rw-r--r--openstack_dashboard/templates/_header.html11
-rw-r--r--openstack_dashboard/templates/_stylesheets.html7
-rw-r--r--openstack_dashboard/test/__init__.py0
-rw-r--r--openstack_dashboard/test/api_tests/__init__.py0
-rw-r--r--openstack_dashboard/test/api_tests/base_tests.py171
-rw-r--r--openstack_dashboard/test/api_tests/cinder_tests.py56
-rw-r--r--openstack_dashboard/test/api_tests/glance_tests.py106
-rw-r--r--openstack_dashboard/test/api_tests/heat_tests.py29
-rw-r--r--openstack_dashboard/test/api_tests/keystone_tests.py118
-rw-r--r--openstack_dashboard/test/api_tests/lbaas_tests.py339
-rw-r--r--openstack_dashboard/test/api_tests/network_tests.py457
-rw-r--r--openstack_dashboard/test/api_tests/neutron_tests.py272
-rw-r--r--openstack_dashboard/test/api_tests/nova_tests.py220
-rw-r--r--openstack_dashboard/test/api_tests/swift_tests.py122
-rw-r--r--openstack_dashboard/test/api_tests/tuskar_tests.py100
-rw-r--r--openstack_dashboard/test/error_pages_urls.py7
-rw-r--r--openstack_dashboard/test/helpers.py398
-rw-r--r--openstack_dashboard/test/settings.py138
-rw-r--r--openstack_dashboard/test/templates/404.html1
-rw-r--r--openstack_dashboard/test/templates/500.html1
-rw-r--r--openstack_dashboard/test/templates/_tab.html1
-rw-r--r--openstack_dashboard/test/templates/base-sidebar.html0
-rw-r--r--openstack_dashboard/test/templates/registration/login.html0
-rw-r--r--openstack_dashboard/test/templates/tab_group.html1
-rw-r--r--openstack_dashboard/test/templates/workflow.html1
-rw-r--r--openstack_dashboard/test/test_data/__init__.py0
-rw-r--r--openstack_dashboard/test/test_data/cinder_data.py47
-rw-r--r--openstack_dashboard/test/test_data/exceptions.py70
-rw-r--r--openstack_dashboard/test/test_data/glance_data.py146
-rw-r--r--openstack_dashboard/test/test_data/heat_data.py340
-rw-r--r--openstack_dashboard/test/test_data/keystone_data.py269
-rw-r--r--openstack_dashboard/test/test_data/neutron_data.py458
-rw-r--r--openstack_dashboard/test/test_data/nova_data.py583
-rw-r--r--openstack_dashboard/test/test_data/swift_data.py40
-rw-r--r--openstack_dashboard/test/test_data/tuskar_data.py159
-rw-r--r--openstack_dashboard/test/test_data/utils.py132
-rw-r--r--openstack_dashboard/test/tests/__init__.py0
-rw-r--r--openstack_dashboard/test/tests/error_pages.py33
-rw-r--r--openstack_dashboard/test/tests/quotas.py187
-rw-r--r--openstack_dashboard/test/tests/selenium.py24
-rw-r--r--openstack_dashboard/test/tests/utils.py42
-rw-r--r--openstack_dashboard/urls.py52
-rw-r--r--openstack_dashboard/usage/__init__.py31
-rw-r--r--openstack_dashboard/usage/base.py317
-rw-r--r--openstack_dashboard/usage/quotas.py158
-rw-r--r--openstack_dashboard/usage/tables.py72
-rw-r--r--openstack_dashboard/usage/views.py56
-rw-r--r--openstack_dashboard/utils/__init__.py0
-rw-r--r--openstack_dashboard/utils/filters.py31
-rw-r--r--openstack_dashboard/views.py38
-rw-r--r--openstack_dashboard/wsgi/django.wsgi15
1011 files changed, 0 insertions, 192163 deletions
diff --git a/doc/Makefile b/doc/Makefile
deleted file mode 100644
index 986ad3df..00000000
--- a/doc/Makefile
+++ /dev/null
@@ -1,153 +0,0 @@
-# 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) source
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
-
-help:
- @echo "Please use \`make <target>' where <target> 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 " 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 " 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 " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
-
-clean:
- -rm -rf $(BUILDDIR)/*
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
- @echo
- @echo "Build finished; now you can process the pickle files."
-
-json:
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-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."
-
-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/Horizon.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Horizon.qhc"
-
-devhelp:
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/Horizon"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Horizon"
- @echo "# devhelp"
-
-epub:
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-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)."
-
-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."
-
-text:
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-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)."
-
-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."
-
-gettext:
- $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
- @echo
- @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-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."
-
-doctest:
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/doc/source/conf.py b/doc/source/conf.py
deleted file mode 100644
index b7089720..00000000
--- a/doc/source/conf.py
+++ /dev/null
@@ -1,426 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Horizon documentation build configuration file, created by
-# sphinx-quickstart on Thu Oct 27 11:38:59 2011.
-#
-# 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.
-
-import sys
-import os
-
-BASE_DIR = os.path.dirname(os.path.abspath(__file__))
-ROOT = os.path.abspath(os.path.join(BASE_DIR, "..", ".."))
-
-sys.path.insert(0, ROOT)
-
-# This is required for ReadTheDocs.org, but isn't a bad idea anyway.
-os.environ['DJANGO_SETTINGS_MODULE'] = 'openstack_dashboard.settings'
-
-import horizon.version
-
-
-def write_autodoc_index():
-
- def find_autodoc_modules(module_name, sourcedir):
- """returns a list of modules in the SOURCE directory"""
- modlist = []
- os.chdir(os.path.join(sourcedir, module_name))
- print "SEARCHING %s" % sourcedir
- for root, dirs, files in os.walk("."):
- for filename in files:
- if filename.endswith(".py"):
- # remove the pieces of the root
- elements = root.split(os.path.sep)
- # replace the leading "." with the module name
- elements[0] = module_name
- # and get the base module name
- base, extension = os.path.splitext(filename)
- if not (base == "__init__"):
- elements.append(base)
- result = ".".join(elements)
- #print result
- modlist.append(result)
- return modlist
-
- RSTDIR = os.path.abspath(os.path.join(BASE_DIR, "sourcecode"))
- SRCS = {'horizon': ROOT,
- 'openstack_dashboard': ROOT}
-
- EXCLUDED_MODULES = ('horizon.tests', 'openstack_dashboard.tests',)
- CURRENT_SOURCES = {}
-
- if not(os.path.exists(RSTDIR)):
- os.mkdir(RSTDIR)
- CURRENT_SOURCES[RSTDIR] = ['autoindex.rst']
-
- INDEXOUT = open(os.path.join(RSTDIR, "autoindex.rst"), "w")
- INDEXOUT.write("=================\n")
- INDEXOUT.write("Source Code Index\n")
- INDEXOUT.write("=================\n")
-
- for modulename, path in SRCS.items():
- sys.stdout.write("Generating source documentation for %s\n" %
- modulename)
- INDEXOUT.write("\n%s\n" % modulename.capitalize())
- INDEXOUT.write("%s\n" % ("=" * len(modulename),))
- INDEXOUT.write(".. toctree::\n")
- INDEXOUT.write(" :maxdepth: 1\n")
- INDEXOUT.write("\n")
-
- MOD_DIR = os.path.join(RSTDIR, modulename)
- CURRENT_SOURCES[MOD_DIR] = []
- if not(os.path.exists(MOD_DIR)):
- os.mkdir(MOD_DIR)
- for module in find_autodoc_modules(modulename, path):
- if any([module.startswith(exclude) for exclude
- in EXCLUDED_MODULES]):
- print "Excluded module %s." % module
- continue
- mod_path = os.path.join(path, *module.split("."))
- generated_file = os.path.join(MOD_DIR, "%s.rst" % module)
-
- INDEXOUT.write(" %s/%s\n" % (modulename, module))
-
- # Find the __init__.py module if this is a directory
- if os.path.isdir(mod_path):
- source_file = ".".join((os.path.join(mod_path, "__init__"),
- "py",))
- else:
- source_file = ".".join((os.path.join(mod_path), "py"))
-
- CURRENT_SOURCES[MOD_DIR].append("%s.rst" % module)
- # Only generate a new file if the source has changed or we don't
- # have a doc file to begin with.
- if not os.access(generated_file, os.F_OK) or \
- os.stat(generated_file).st_mtime < \
- os.stat(source_file).st_mtime:
- print "Module %s updated, generating new documentation." \
- % module
- FILEOUT = open(generated_file, "w")
- header = "The :mod:`%s` Module" % module
- FILEOUT.write("%s\n" % ("=" * len(header),))
- FILEOUT.write("%s\n" % header)
- FILEOUT.write("%s\n" % ("=" * len(header),))
- FILEOUT.write(".. automodule:: %s\n" % module)
- FILEOUT.write(" :members:\n")
- FILEOUT.write(" :undoc-members:\n")
- FILEOUT.write(" :show-inheritance:\n")
- FILEOUT.write(" :noindex:\n")
- FILEOUT.close()
-
- INDEXOUT.close()
-
- # Delete auto-generated .rst files for sources which no longer exist
- for directory, subdirs, files in list(os.walk(RSTDIR)):
- for old_file in files:
- if old_file not in CURRENT_SOURCES.get(directory, []):
- print "Removing outdated file for %s" % old_file
- os.remove(os.path.join(directory, old_file))
-
-
-write_autodoc_index()
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
-
-# -- General configuration ----------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings.
-# They can be extensions coming with Sphinx (named 'sphinx.ext.*')
-# or your custom ones.
-extensions = ['sphinx.ext.autodoc',
- 'sphinx.ext.intersphinx',
- 'sphinx.ext.todo',
- 'sphinx.ext.coverage',
- 'sphinx.ext.pngmath',
- 'sphinx.ext.viewcode',
- 'oslo.sphinx',
- ]
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'Horizon'
-copyright = u'2012, OpenStack, LLC'
-
-# 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 = horizon.version.version_info.version_string()
-# The full version, including alpha/beta/rc tags.
-release = horizon.version.version_info.release_string()
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['**/#*', '**~', '**/#*#']
-
-# The reST default role (used for this markup: `text`)
-# to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-primary_domain = 'py'
-nitpicky = 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_path = ['.']
-# html_theme = '_theme'
-
-# 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 = {
- "nosidebar": "false"
-}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-git_cmd = "git log --pretty=format:'%ad, commit %h' --date=local -n1"
-html_last_updated_fmt = os.popen(git_cmd).read()
-
-# 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 <link> tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'Horizondoc'
-
-
-# -- Options for LaTeX output -------------------------------------------------
-
-latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass
-# [howto/manual]).
-latex_documents = [
- ('index', 'Horizon.tex', u'Horizon Documentation',
- u'OpenStack, LLC', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output -------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- ('index', 'horizon', u'Horizon Documentation',
- [u'OpenStack'], 1)
-]
-
-# If true, show URL addresses after external links.
-#man_show_urls = False
-
-
-# -- Options for Texinfo output -----------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-# dir menu entry, description, category)
-texinfo_documents = [
- ('index', 'Horizon', u'Horizon Documentation', u'OpenStack',
- 'Horizon', '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'
-
-
-# -- Options for Epub output --------------------------------------------------
-
-# Bibliographic Dublin Core info.
-epub_title = u'Horizon'
-epub_author = u'OpenStack'
-epub_publisher = u'OpenStack'
-epub_copyright = u'2012, OpenStack'
-
-# The language of the text. It defaults to the language option
-# or en if the language is not set.
-#epub_language = ''
-
-# The scheme of the identifier. Typical schemes are ISBN or URL.
-#epub_scheme = ''
-
-# The unique identifier of the text. This can be an ISBN number
-# or the project homepage.
-#epub_identifier = ''
-
-# A unique identification for the text.
-#epub_uid = ''
-
-# A tuple containing the cover image and cover page html template filenames.
-#epub_cover = ()
-
-# HTML files that should be inserted before the pages created by sphinx.
-# The format is a list of tuples containing the path and title.
-#epub_pre_files = []
-
-# HTML files shat should be inserted after the pages created by sphinx.
-# The format is a list of tuples containing the path and title.
-#epub_post_files = []
-
-# A list of files that should not be packed into the epub file.
-#epub_exclude_files = []
-
-# The depth of the table of contents in toc.ncx.
-#epub_tocdepth = 3
-
-# Allow duplicate toc entries.
-#epub_tocdup = True
-
-
-# Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {'python': ('http://docs.python.org/', None),
- 'django':
- ('http://docs.djangoproject.com/en/dev/_objects/'),
- 'nova': ('http://nova.openstack.org', None),
- 'swift': ('http://swift.openstack.org', None),
- 'keystone': ('http://keystone.openstack.org', None),
- 'glance': ('http://glance.openstack.org', None)}
diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst
deleted file mode 100644
index fada39da..00000000
--- a/doc/source/contributing.rst
+++ /dev/null
@@ -1,203 +0,0 @@
-==================
-Contributing Guide
-==================
-
-First and foremost, thank you for wanting to contribute! It's the only way
-open source works!
-
-Before you dive into writing patches, here are some of the basics:
-
-* Project page: http://launchpad.net/horizon
-* Bug tracker: https://bugs.launchpad.net/horizon
-* Source code: https://github.com/openstack/horizon
-* Code review: https://review.openstack.org/#q,status:open+project:openstack/horizon,n,z
-* Jenkins build status: https://jenkins.openstack.org/view/Horizon/
-* IRC Channel: #openstack-horizon on Freenode.
-
-Making Contributions
-====================
-
-Getting Started
----------------
-
-We'll start by assuming you've got a working checkout of the repository (if
-not then please see the :doc:`quickstart`).
-
-Second, you'll need to take care of a couple administrative tasks:
-
-#. Create an account on Launchpad.
-#. Sign the `OpenStack Contributor License Agreement`_ and follow the associated
- instructions to verify your signature.
-#. Join the `Horizon Developers`_ team on Launchpad.
-#. Follow the `instructions for setting up git-review`_ in your
- development environment.
-
-Whew! Got that all that? Okay! You're good to go.
-
-Ways To Contribute
-------------------
-
-The easiest way to get started with Horizon's code is to pick a bug on
-Launchpad that interests you, and start working on that. Alternatively, if
-there's an OpenStack API feature you would like to see implemented in Horizon
-feel free to try building it.
-
-If those are too big, there are lots of great ways to get involved without
-plunging in head-first:
-
-* Report bugs, triage new tickets, and review old tickets on
- the `bug tracker`_.
-* Propose ideas for improvements via Launchpad Blueprints, via the
- mailing list on the project page, or on IRC.
-* Write documentation!
-* Write unit tests for untested code!
-
-.. _`bug tracker`: https://bugs.launchpad.net/horizon
-
-Choosing Issues To Work On
---------------------------
-
-In general, if you want to write code, there are three cases for issues
-you might want to work on:
-
-#. Confirmed bugs
-#. Approved blueprints (features)
-#. New bugs you've discovered
-
-If you have an idea for a new feature that isn't in a blueprint yet, it's
-a good idea to write the blueprint first so you don't end up writing a bunch
-of code that may not go in the direction the community wants.
-
-For bugs, open the bug first, but if you can reproduce the bug reliably and
-identify its cause then it's usually safe to start working on it. However,
-getting independent confirmation (and verifying that it's not a duplicate)
-is always a good idea if you can be patient.
-
-After You Write Your Patch
---------------------------
-
-Once you've made your changes, there are a few things to do:
-
-* Make sure the unit tests pass: ``./run_tests.sh``
-* Make sure PEP8 is clean: ``./run_tests.sh --pep8``
-* Make sure your code is up-to-date with the latest master: ``git pull --rebase``
-* Finally, run ``git review`` to upload your changes to Gerrit for review.
-
-The Horizon core developers will be notified of the new review and will examine
-it in a timely fashion, either offering feedback or approving it to be merged.
-If the review is approved, it is sent to Jenkins to verify the unit tests pass
-and it can be merged cleanly. Once Jenkins approves it, the change will be
-merged to the master repository and it's time to celebrate!
-
-.. _`OpenStack Contributor License Agreement`: http://wiki.openstack.org/CLA
-.. _`OpenStack Contributors`: https://launchpad.net/~openstack-cla
-.. _`Horizon Developers`: https://launchpad.net/~horizon
-.. _`instructions for setting up git-review`: http://wiki.openstack.org/GerritWorkflow
-
-Etiquette
-=========
-
-The community's guidelines for etiquette are fairly simple:
-
-* Treat everyone respectfully and professionally.
-* If a bug is "in progress" in the bug tracker, don't start working on it
- without contacting the author. Try on IRC, or via the launchpad email
- contact link. If you don't get a response after a reasonable time, then go
- ahead. Checking first avoids duplicate work and makes sure nobody's toes
- get stepped on.
-* If a blueprint is assigned, even if it hasn't been started, be sure you
- contact the assignee before taking it on. These larger issues often have a
- history of discussion or specific implementation details that the assignee
- may be aware of that you are not.
-* Please don't re-open tickets closed by a core developer. If you disagree with
- the decision on the ticket, the appropriate solution is to take it up on
- IRC or the mailing list.
-* Give credit where credit is due; if someone helps you substantially with
- a piece of code, it's polite (though not required) to thank them in your
- commit message.
-
-Code Style
-==========
-
-Python
-------
-
-We follow PEP8_ for all our Python code, and use ``pep8.py`` (available
-via the shortcut ``./run_tests.sh --pep8``) to validate that our code
-meets proper Python style guidelines.
-
-.. _PEP8: http://www.python.org/dev/peps/pep-0008/
-
-Django
-------
-
-Additionally, we follow `Django's style guide`_ for templates, views, and
-other miscellany.
-
-.. _Django's style guide: https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/
-
-JavaScript
-----------
-
-As a project, Horizon adheres to code quality standards for our JavaScript
-just as we do for our Python. To that end we recommend (but do not strictly
-enforce) the use of JSLint_ to validate some general best practices.
-
-The default options are mostly good, but the following accommodate some
-allowances we make:
-
-* Set ``Indentation`` to ``2``.
-* Enable the ``Assume console, alert, ...`` option.
-* Enable the ``Assume a browser`` option.
-* Enable the ``Tolerate missing 'use strict' pragma`` option.
-* Clear the ``Maximum number of errors`` field.
-* Add ``horizon,$`` to the ``Predefined`` list.
-
-.. _JSLint: http://jslint.com/
-
-CSS
----
-
-Style guidelines for CSS are currently quite minimal. Do your best to make the
-code readable and well-organized. Two spaces are preferred for indentation
-so as to match both the JavaScript and HTML files.
-
-HTML
-----
-
-Again, readability is paramount; however be conscientous of how the browser
-will handle whitespace when rendering the output. Two spaces is the preferred
-indentation style to match all front-end code.
-
-Documentation
--------------
-
-Horizon's documentation is written in reStructuredText and uses Sphinx for
-additional parsing and functionality, and should follow
-standard practices for writing reST. This includes:
-
-* Flow paragraphs such that lines wrap at 80 characters or less.
-* Use proper grammar, spelling, capitalization and punctuation at all times.
-* Make use of Sphinx's autodoc feature to document modules, classes
- and functions. This keeps the docs close to the source.
-* Where possible, use Sphinx's cross-reference syntax (e.g.
- ``:class:`~horizon.foo.Bar```) when referring to other Horizon components.
- The better-linked our docs are, the easier they are to use.
-
-Be sure to generate the documentation before submitting a patch for review.
-Unexpected warnings often appear when building the documentation, and slight
-reST syntax errors frequently cause links or cross-references not to work
-correctly.
-
-Conventions
------------
-
-Simply by convention, we have a few rules about naming:
-
- * The term "project" is used in place of Keystone's "tenant" terminology
- in all user-facing text. The term "tenant" is still used in API code to
- make things more obvious for developers.
-
- * The term "dashboard" refers to a top-level dashboard class, and "panel" to
- the sub-items within a dashboard. Referring to a panel as a dashboard is
- both confusing and incorrect.
diff --git a/doc/source/faq.rst b/doc/source/faq.rst
deleted file mode 100644
index 26836ef6..00000000
--- a/doc/source/faq.rst
+++ /dev/null
@@ -1,37 +0,0 @@
-==========================
-Frequently Asked Questions
-==========================
-
-What is the relationship between ``Dashboards``, ``Panels``, and navigation?
-
- The navigational structure is strongly encouraged to flow from
- ``Dashboard`` objects as top-level navigation items to ``Panel`` objects as
- sub-navigation items as in the current implementation. Template tags
- are provided to automatically generate this structure.
-
- That said, you are not required to use the provided tools and can write
- templates and URLconfs by hand to create any desired structure.
-
-Does a panel have to be an app in ``INSTALLED_APPS``?
-
- A panel can live in any Python module. It can be a standalone which ties
- into an existing dashboard, or it can be contained alongside others within
- a larger dashboard "app". There is no strict enforcement here. Python
- is "a language for consenting adults." A module containing a Panel does
- not need to be added to ``INSTALLED_APPS``, but this is a common and
- convenient way to load a standalone panel.
-
-Could I hook an external service into a panel using, for example, an iFrame?
-
- Panels are just entry-points to hook views into the larger dashboard
- navigational structure and enforce common attributes like RBAC. The
- view and corresponding templates can contain anything you would like,
- including iFrames.
-
-What does this mean for visual design?
-
- The ability to add an arbitrary number of top-level navigational items
- (``Dashboard`` objects) poses a new design challenge. Horizon's lead
- designer has taken on the challenge of providing a reference design
- for Horizon which supports this possibility.
-
diff --git a/doc/source/glossary.rst b/doc/source/glossary.rst
deleted file mode 100644
index 7cabc2f4..00000000
--- a/doc/source/glossary.rst
+++ /dev/null
@@ -1,24 +0,0 @@
-========
-Glossary
-========
-
-Horizon
-
- The OpenStack dashboard project. Also the name of the top-level
- Python object which handles registration for the app.
-
-Dashboard
-
- A Python class representing a top-level navigation item (e.g. "project")
- which provides a consistent API for Horizon-compatible applications.
-
-Panel
-
- A Python class representing a sub-navigation item (e.g. "instances")
- which contains all the necessary logic (views, forms, tests, etc.) for
- that interface.
-
-Project
-
- Used in user-facing text in place of the term "Tenant" which is Keystone's
- word.
diff --git a/doc/source/index.rst b/doc/source/index.rst
deleted file mode 100644
index 592027a2..00000000
--- a/doc/source/index.rst
+++ /dev/null
@@ -1,127 +0,0 @@
-..
- Copyright 2012 OpenStack, LLC
- All Rights Reserved.
-
- Licensed under the Apache License, Version 2.0 (the "License"); you may
- not use this file except in compliance with the License. You may obtain
- a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- License for the specific language governing permissions and limitations
- under the License.
-
-========================================
-Horizon: The OpenStack Dashboard Project
-========================================
-
-Introduction
-============
-
-Horizon is the canonical implementation of `Openstack's Dashboard
-<https://github.com/openstack/horizon>`_, which provides a web based user
-interface to OpenStack services including Nova, Swift, Keystone, etc.
-
-For a more in-depth look at Horizon and its architecture, see the
-:doc:`Introduction to Horizon <intro>`.
-
-To learn what you need to know to get going, see the :doc:`quickstart`.
-
-Getting Started With Horizon
-============================
-
-How to use Horizon in your own projects.
-
-.. toctree::
- :maxdepth: 1
-
- intro
- quickstart
- topics/tutorial
- topics/deployment
- topics/settings
- topics/customizing
-
-Developer Docs
-==============
-
-For those wishing to develop Horizon itself, or go in-depth with building
-your own :class:`~horizon.Dashboard` or :class:`~horizon.Panel` classes,
-the following documentation is provided.
-
-General information
--------------------
-
-Brief guides to areas of interest and importance when developing Horizon.
-
-.. toctree::
- :maxdepth: 1
-
- contributing
- testing
-
-Topic Guides
-------------
-
-Information on how to work with specific areas of Horizon can be found in
-the following topic guides.
-
-.. toctree::
- :maxdepth: 1
-
- topics/tables
- topics/testing
-
-API Reference
--------------
-
-In-depth documentation for Horizon and its APIs.
-
-.. toctree::
- :maxdepth: 1
-
- ref/run_tests
- ref/horizon
- ref/workflows
- ref/tables
- ref/tabs
- ref/forms
- ref/middleware
- ref/context_processors
- ref/decorators
- ref/exceptions
- ref/test
-
-Source Code Reference
----------------------
-
-Auto-generated reference for the complete source code.
-
-.. toctree::
- :maxdepth: 1
-
- sourcecode/autoindex
-
-Release Notes
-=============
-
-.. toctree::
- :glob:
- :maxdepth: 1
-
- releases/*
-
-Information
-===========
-
-.. toctree::
- :maxdepth: 1
-
- faq
- glossary
-
-* :ref:`genindex`
-* :ref:`modindex`
diff --git a/doc/source/intro.rst b/doc/source/intro.rst
deleted file mode 100644
index a546ce99..00000000
--- a/doc/source/intro.rst
+++ /dev/null
@@ -1,124 +0,0 @@
-===================
-Introducing Horizon
-===================
-
-.. contents:: Contents:
- :local:
-
-Values
-======
-
- "Think simple" as my old master used to say - meaning reduce
- the whole of its parts into the simplest terms, getting back
- to first principles.
-
- -- Frank Lloyd Wright
-
-Horizon holds several key values at the core of its design and architecture:
-
- * Core Support: Out-of-the-box support for all core OpenStack projects.
- * Extensible: Anyone can add a new component as a "first-class citizen".
- * Manageable: The core codebase should be simple and easy-to-navigate.
- * Consistent: Visual and interaction paradigms are maintained throughout.
- * Stable: A reliable API with an emphasis on backwards-compatibility.
- * Usable: Providing an *awesome* interface that people *want* to use.
-
-The only way to attain and uphold those ideals is to make it *easy* for
-developers to implement those values.
-
-History
-=======
-
-Horizon started life as a single app to manage OpenStack's compute project.
-As such, all it needed was a set of views, templates, and API calls.
-
-From there it grew to support multiple OpenStack projects and APIs gradually,
-arranged rigidly into "dash" and "syspanel" groupings.
-
-During the "Diablo" release cycle an initial plugin system was added using
-signals to hook in additional URL patterns and add links into the "dash"
-and "syspanel" navigation.
-
-This incremental growth served the goal of "Core Support" phenomenally, but
-left "Extensible" and "Manageable" behind. And while the other key values took
-shape of their own accord, it was time to re-architect for an extensible,
-modular future.
-
-
-The Current Architecture & How It Meets Our Values
-==================================================
-
-At its core, **Horizon should be a registration pattern for
-applications to hook into**. Here's what that means and how it is
-implemented in terms of our values:
-
-Core Support
-------------
-
-Horizon ships with three central dashboards, a "User Dashboard", a
-"System Dashboard", and a "Settings" dashboard. Between these three they
-cover the core OpenStack applications and deliver on Core Support.
-
-The Horizon application also ships with a set of API abstractions
-for the core OpenStack projects in order to provide a consistent, stable set
-of reusable methods for developers. Using these abstractions, developers
-working on Horizon don't need to be intimately familiar with the APIs of
-each OpenStack project.
-
-Extensible
-----------
-
-A Horizon dashboard application is based around the :class:`~horizon.Dashboard`
-class that provides a consistent API and set of capabilities for both
-core OpenStack dashboard apps shipped with Horizon and equally for third-party
-apps. The :class:`~horizon.Dashboard` class is treated as a top-level
-navigation item.
-
-Should a developer wish to provide functionality within an existing dashboard
-(e.g. adding a monitoring panel to the user dashboard) the simple registration
-pattern makes it possible to write an app which hooks into other dashboards
-just as easily as creating a new dashboard. All you have to do is import the
-dashboard you wish to modify.
-
-Manageable
-----------
-
-Within the application, there is a simple method for registering a
-:class:`~horizon.Panel` (sub-navigation items). Each panel contains the
-necessary logic (views, forms, tests, etc.) for that interface. This granular
-breakdown prevents files (such as ``api.py``) from becoming thousands of
-lines long and makes code easy to find by correlating it directly to the
-navigation.
-
-Consistent
-----------
-
-By providing the necessary core classes to build from, as well as a
-solid set of reusable templates and additional tools (base form classes,
-base widget classes, template tags, and perhaps even class-based views)
-we can maintain consistency across applications.
-
-Stable
-------
-
-By architecting around these core classes and reusable components we
-create an implicit contract that changes to these components will be
-made in the most backwards-compatible ways whenever possible.
-
-Usable
-------
-
-Ultimately that's up to each and every developer that touches the code,
-but if we get all the other goals out of the way then we are free to focus
-on the best possible experience.
-
-.. seealso::
-
- :doc:`Quickstart <quickstart>`
- A short guide to getting started with using Horizon.
-
- :doc:`Frequently Asked Questions <faq>`
- Common questions and answers.
-
- :doc:`Glossary <glossary>`
- Common terms and their definitions.
diff --git a/doc/source/quickstart.rst b/doc/source/quickstart.rst
deleted file mode 100644
index 3c7156c6..00000000
--- a/doc/source/quickstart.rst
+++ /dev/null
@@ -1,214 +0,0 @@
-==================
-Horizon Quickstart
-==================
-
-Setup
-=====
-
-To setup an Horizon development environment simply clone the Horizon git
-repository from http://github.com/openstack/horizon and execute the
-``run_tests.sh`` script from the root folder (see :doc:`ref/run_tests`)::
-
- > git clone https://github.com/openstack/horizon.git
- > cd horizon
- > ./run_tests.sh
-
-Next you will need to setup your Django application config by copying ``openstack_dashboard/local/local_settings.py.example`` to ``openstack_dashboard/local_settings.py``. To do this quickly you can use the following command::
-
- > cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py
-
-Horizon assumes a single end-point for OpenStack services which defaults to
-the local host (127.0.0.1). If this is not the case change the
-``OPENSTACK_HOST`` setting in the ``openstack_dashboard/local/local_settings.py`` file, to the actual IP address of the OpenStack end-point Horizon should use.
-
-To start the Horizon development server use the Django ``manage.py`` utility
-with the context of the virtual environment::
-
- > tools/with_venv.sh ./manage.py runserver
-
-Alternately specify the listen IP and port::
-
- > tools/with_venv.sh ./manage.py runserver 0.0.0.0:8080
-
-.. note::
-
- If you would like to run commands without the prefix of ``tools/with_venv.sh`` you may source your environment directly. This will remain active as long as your shell session stays open::
-
- > source .venv/bin/activate
-
-
-Once the Horizon server is running point a web browser to http://localhost:8000
-or to the IP and port the server is listening for.
-
-.. note::
-
- The ``DevStack`` project (http://devstack.org/) can be used to install
- an OpenStack development environment from scratch.
-
-.. note::
-
- The minimum required set of OpenStack services running includes the
- following:
-
- * Nova (compute, api, scheduler, and network)
- * Glance
- * Keystone
-
- Optional support is provided for Swift.
-
-Horizon's Structure
-===================
-
-This project is a bit different from other OpenStack projects in that it has
-two very distinct components underneath it: ``horizon``, and
-``openstack_dashboard``.
-
-The ``horizon`` directory holds the generic libraries and components that can
-be used in any Django project.
-
-The ``openstack_dashboard`` directory contains a reference Django project that
-uses ``horizon``.
-
-For development, both pieces share an environment which (by default) is
-built with the ``tools/install_venv.py`` script. That script creates a
-virtualenv and installs all the necessary packages.
-
-If dependencies are added to either ``horizon`` or ``openstack_dashboard``,
-they should be added to ``requirements.txt``.
-
- .. important::
-
- If you do anything which changes the environment (adding new dependencies
- or renaming directories are both great examples) be sure to increment the
- ``environment_version`` counter in :doc:`run_tests.sh <ref/run_tests>`.
-
-Project
-=======
-
-INSTALLED_APPS
---------------
-
-At the project level you add Horizon and any desired dashboards to your
-``settings.INSTALLED_APPS``::
-
- INSTALLED_APPS = (
- 'openstack_dashboard',
- ...
- 'horizon',
- 'openstack_dashboard.dashboards.project',
- 'openstack_dashboard.dashboards.admin',
- 'openstack_dashboard.dashboards.settings',
- ...
- )
-
-URLs
-----
-
-Then you add a single line to your project's ``urls.py``::
-
- url(r'', include(horizon.urls)),
-
-Those urls are automatically constructed based on the registered Horizon apps.
-If a different URL structure is desired it can be constructed by hand.
-
-Templates
----------
-
-Pre-built template tags generate navigation. In your ``nav.html``
-template you might have the following::
-
- {% load horizon %}
-
- <div class='nav'>
- {% horizon_main_nav %}
- </div>
-
-And in your ``sidebar.html`` you might have::
-
- {% load horizon %}
-
- <div class='sidebar'>
- {% horizon_dashboard_nav %}
- </div>
-
-These template tags are aware of the current "active" dashboard and panel
-via template context variables and will render accordingly.
-
-Application
-===========
-
-Structure
----------
-
-An application would have the following structure (we'll use syspanel as
-an example)::
-
- project/
- |---__init__.py
- |---dashboard.py <-----Registers the app with Horizon and sets dashboard properties
- |---overview/
- |---images_and_snapshots/
- |-- images
- |-- __init__.py
- |---panel.py <-----Registers the panel in the app and defines panel properties
- |-- snapshots/
- |-- templates/
- |-- tests.py
- |-- urls.py
- |-- views.py
- ...
- ...
-
-Dashboard Classes
------------------
-
-Inside of ``dashboard.py`` you would have a class definition and the registration
-process::
-
- import horizon
-
- ....
- # ObjectStorePanels is an example for a PanelGroup
- # for panel classes in general, see below
- class ObjectStorePanels(horizon.PanelGroup):
- slug = "object_store"
- name = _("Object Store")
- panels = ('containers',)
-
-
- class Project(horizon.Dashboard):
- name = _("Project") # Appears in navigation
- slug = "project" # Appears in URL
- # panels may be strings or refer to classes, such as
- # ObjectStorePanels
- panels = (BasePanels, NetworkPanels, ObjectStorePanels)
- default_panel = 'overview'
- supports_tenants = True
- ...
-
- horizon.register(Project)
-
-Panel Classes
--------------
-
-To connect a :class:`~horizon.Panel` with a :class:`~horizon.Dashboard` class
-you register it in a ``panels.py`` file like so::
-
- import horizon
-
- from openstack_dashboard.dashboards.project import dashboard
-
-
- class Images(horizon.Panel):
- name = "Images"
- slug = 'images'
- permissions = ('openstack.roles.admin', 'my.other.permission',)
-
-
- # You could also register your panel with another application's dashboard
- dashboard.Project.register(Images)
-
-By default a :class:`~horizon.Panel` class looks for a ``urls.py`` file in the
-same directory as ``panel.py`` to include in the rollup of url patterns from
-panels to dashboards to Horizon, resulting in a wholly extensible, configurable
-URL structure.
diff --git a/doc/source/ref/context_processors.rst b/doc/source/ref/context_processors.rst
deleted file mode 100644
index b34c0109..00000000
--- a/doc/source/ref/context_processors.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-==========================
-Horizon Context Processors
-==========================
-
-.. automodule:: horizon.context_processors
- :members:
diff --git a/doc/source/ref/decorators.rst b/doc/source/ref/decorators.rst
deleted file mode 100644
index 777afbe5..00000000
--- a/doc/source/ref/decorators.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-==================
-Horizon Decorators
-==================
-
-.. automodule:: horizon.decorators
- :members:
diff --git a/doc/source/ref/exceptions.rst b/doc/source/ref/exceptions.rst
deleted file mode 100644
index 4151f18f..00000000
--- a/doc/source/ref/exceptions.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-==================
-Horizon Exceptions
-==================
-
-.. automodule:: horizon.exceptions
- :members:
diff --git a/doc/source/ref/forms.rst b/doc/source/ref/forms.rst
deleted file mode 100644
index f0a0507c..00000000
--- a/doc/source/ref/forms.rst
+++ /dev/null
@@ -1,98 +0,0 @@
-=============
-Horizon Forms
-=============
-
-Horizon ships with some very useful base form classes, form fields,
-class-based views, and javascript helpers which streamline most of the common
-tasks related to form handling.
-
-Form Classes
-============
-
-.. automodule:: horizon.forms.base
- :members:
-
-Form Fields
-===========
-
-.. automodule:: horizon.forms.fields
- :members:
-
-Form Views
-==========
-
-.. automodule:: horizon.forms.views
- :members:
-
-Forms Javascript
-================
-
-Switchable Fields
------------------
-
-By marking fields with the ``"switchable"`` and ``"switched"`` classes along
-with defining a few data attributes you can programmatically hide, show,
-and rename fields in a form.
-
-The triggers are fields using a ``select`` input widget, marked with the
-"switchable" class, and defining a "data-slug" attribute. When they are changed,
-any input with the ``"switched"`` class and defining a ``"data-switch-on"``
-attribute which matches the ``select`` input's ``"data-slug"`` attribute will be
-evaluated for necessary changes. In simpler terms, if the ``"switched"`` target
-input's ``"switch-on"`` matches the ``"slug"`` of the ``"switchable"`` trigger
-input, it gets switched. Simple, right?
-
-The ``"switched"`` inputs also need to define states. For each state in which
-the input should be shown, it should define a data attribute like the
-following: ``data-<slug>-<value>="<desired label>"``. When the switch event
-happens the value of the ``"switchable"`` field will be compared to the
-data attributes and the correct label will be applied to the field. If
-a corresponding label for that value is *not* found, the field will
-be hidden instead.
-
-A simplified example is as follows::
-
- source = forms.ChoiceField(
- label=_('Source'),
- choices=[
- ('cidr', _('CIDR')),
- ('sg', _('Security Group'))
- ],
- widget=forms.Select(attrs={
- 'class': 'switchable',
- 'data-slug': 'source'
- })
- )
-
- cidr = fields.IPField(
- label=_("CIDR"),
- required=False,
- widget=forms.TextInput(attrs={
- 'class': 'switched',
- 'data-switch-on': 'source',
- 'data-source-cidr': _('CIDR')
- })
- )
-
- security_group = forms.ChoiceField(
- label=_('Security Group'),
- required=False,
- widget=forms.Select(attrs={
- 'class': 'switched',
- 'data-switch-on': 'source',
- 'data-source-sg': _('Security Group')
- })
- )
-
-That code would create the ``"switchable"`` control field ``source``, and the
-two ``"switched"`` fields ``cidr`` and ``security group`` which are hidden or
-shown depending on the value of ``source``.
-
-
-NOTE: A field can only safely define one slug in its ``"switch-on"`` attribute.
-While switching on multiple fields is possible, the behavior is very hard to
-predict due to the events being fired from the various switchable fields in
-order. You generally end up just having it hidden most of the time by accident,
-so it's not recommended. Instead just add a second field to the form and control
-the two independently, then merge their results in the form's clean or handle
-methods at the end.
diff --git a/doc/source/ref/horizon.rst b/doc/source/ref/horizon.rst
deleted file mode 100644
index cc4b2d70..00000000
--- a/doc/source/ref/horizon.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-======================
-The ``horizon`` Module
-======================
-
-.. module:: horizon
-
-Horizon ships with a single point of contact for hooking into your project if
-you aren't developing your own :class:`~horizon.Dashboard` or
-:class:`~horizon.Panel`::
-
- import horizon
-
-From there you can access all the key methods you need.
-
-Horizon
-=======
-
-.. attribute:: urls
-
- The auto-generated URLconf for Horizon. Usage::
-
- url(r'', include(horizon.urls)),
-
-.. autofunction:: register
-.. autofunction:: unregister
-.. autofunction:: get_absolute_url
-.. autofunction:: get_user_home
-.. autofunction:: get_dashboard
-.. autofunction:: get_default_dashboard
-.. autofunction:: get_dashboards
-
-Dashboard
-=========
-
-.. autoclass:: Dashboard
- :members:
-
-Panel
-=====
-
-.. autoclass:: Panel
- :members:
-
-.. autoclass:: PanelGroup
- :members:
diff --git a/doc/source/ref/middleware.rst b/doc/source/ref/middleware.rst
deleted file mode 100644
index fcca5ff0..00000000
--- a/doc/source/ref/middleware.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-==================
-Horizon Middleware
-==================
-
-.. automodule:: horizon.middleware
- :members:
diff --git a/doc/source/ref/run_tests.rst b/doc/source/ref/run_tests.rst
deleted file mode 100644
index ca7c7ce1..00000000
--- a/doc/source/ref/run_tests.rst
+++ /dev/null
@@ -1,233 +0,0 @@
-===========================
-The ``run_tests.sh`` Script
-===========================
-
-.. contents:: Contents:
- :local:
-
-Horizon ships with a script called ``run_tests.sh`` at the root of the
-repository. This script provides many crucial functions for the project,
-and also makes several otherwise complex tasks trivial for you as a
-developer.
-
-First Run
-=========
-
-If you start with a clean copy of the Horizon repository, the first thing
-you should do is to run ``./run_tests.sh`` from the root of the repository.
-This will do two things for you:
-
- #. Set up a virtual environment for both the ``horizon`` module and
- the ``openstack-dashboard`` project using
- ``openstack-dashboard/tools/install_venv.py``.
- #. Run the tests for both ``horizon`` and ``openstack-dashboard`` using
- their respective environments and verify that evreything is working.
-
-Setting up the environment the first time can take several minutes, but only
-needs to be done once. If dependencies are added in the future, updating the
-environments will be necessary but not as time consuming.
-
-I just want to run the tests!
-=============================
-
-Running the full set of unit tests quickly and easily is the main goal of this
-script. All you need to do is::
-
- ./run_tests.sh
-
-Yep, that's it. However, for a more thorough test run you can include the
-Selenium tests by using the ``--with-selenium`` flag::
-
- ./run_tests.sh --with-selenium
-
-If you run horizon in a minimal installation VM, you will probably need
-the following (steps for Fedora 18 minimal installation):
-
- #. Install these packages in the VM:
- ``yum install xorg-x11-xauth xorg-x11-fonts-Type1.noarch``.
- #. Install firefox in the VM:
- ``yum install firefox``.
- #. Connect to the VM by ``ssh -X``
- (if you run ``set|grep DISP``, you should see that the DISPLAY is set).
- #. Run
- ``./run_tests.sh --with-selenium``.
-
-Running a subset of tests
--------------------------
-
-Instead of running all tests, you can specify an individual directory, file,
-class, or method that contains test code.
-
-To run the tests in the ``horizon/test/tests/tables.py`` file::
-
- ./run_tests.sh horizon.test.tests.tables
-
-To run the tests in the `WorkflowsTests` class in
-``horizon/test/tests/workflows``::
-
- ./run_tests.sh horizon.test.tests.workflows:WorkflowsTests
-
-To run just the `WorkflowsTests.test_workflow_view` test method::
-
- ./run_tests.sh horizon.test.tests.workflows:WorkflowsTests.test_workflow_view
-
-Using Dashboard and Panel Templates
-===================================
-
-Horizon has a set of convenient management commands for creating new
-dashboards and panels based on basic templates.
-
-Dashboards
-----------
-
-To create a new dashboard, run the following:
-
- ./run_tests.sh -m startdash <dash_name>
-
-This will create a directory with the given dashboard name, a ``dashboard.py``
-module with the basic dashboard code filled in, and various other common
-"boilerplate" code.
-
-Available options:
-
-* --target: the directory in which the dashboard files should be created.
- Default: A new directory within the current directory.
-
-Panels
-------
-
-To create a new panel, run the following:
-
- ./run_tests -m startpanel <panel_name> --dashboard=<dashboard_path>
-
-This will create a directory with the given panel name, and ``panel.py``
-module with the basic panel code filled in, and various other common
-"boilerplate" code.
-
-Available options:
-
-* -d, --dashboard: The dotted python path to your dashboard app (the module
- which containers the ``dashboard.py`` file.).
-* --target: the directory in which the panel files should be created.
- If the value is ``auto`` the panel will be created as a new directory inside
- the dashboard module's directory structure. Default: A new directory within
- the current directory.
-
-Give me metrics!
-================
-
-You can generate various reports and metrics using command line arguments
-to ``run_tests.sh``.
-
-Coverage
---------
-
-To run coverage reports::
-
- ./run_tests.sh --coverage
-
-The reports are saved to ``./reports/`` and ``./coverage.xml``.
-
-PEP8
-----
-
-You can check for PEP8 violations as well::
-
- ./run_tests.sh --pep8
-
-The results are saved to ``./pep8.txt``.
-
-PyLint
-------
-
-For more detailed code analysis you can run::
-
- ./run_tests.sh --pylint
-
-The output will be saved in ``./pylint.txt``.
-
-Tab Characters
---------------
-
-For those who dislike having a mix of tab characters and spaces for indentation
-there's a command to check for that in Python, CSS, JavaScript and HTML files::
-
- ./run_tests.sh --tabs
-
-This will output a total "tab count" and a list of the offending files.
-
-Running the development server
-==============================
-
-As an added bonus, you can run Django's development server directly from
-the root of the repository with ``run_tests.sh`` like so::
-
- ./run_tests.sh --runserver
-
-This is effectively just an alias for::
-
- ./openstack-dashboard/tools/with_venv.sh ./openstack-dashboard/dashboard/manage.py runserver
-
-Generating the documentation
-============================
-
-You can build Horizon's documentation automatically by running::
-
- ./run_tests.sh --docs
-
-The output is stored in ``./doc/build/html/``.
-
-Updating the translation files
-==============================
-
-You can update all of the translation files for both the ``horizon`` app and
-``openstack_dashboard`` project with a single command:
-
- ./run_tests.sh --makemessages
-
-or, more compactly:
-
- ./run_tests.sh --m
-
-Starting clean
-==============
-
-If you ever want to start clean with a new environment for Horizon, you can
-run::
-
- ./run_tests.sh --force
-
-That will blow away the existing environments and create new ones for you.
-
-Non-interactive Mode
-====================
-
-There is an optional flag which will run the script in a non-interactive
-(and eventually less verbose) mode::
-
- ./run_tests.sh --quiet
-
-This will automatically take the default action for actions which would
-normally prompt for user input such as installing/updating the environment.
-
-Environment Backups
-===================
-
-To speed up the process of doing clean checkouts, running continuous
-integration tests, etc. there are options for backing up the current
-environment and restoring from a backup.
-
- ./run_tests.sh --restore-environment
- ./run_tests.sh --backup-environment
-
-The environment backup is stored in ``/tmp/.horizon_environment/``.
-
-Environment Versioning
-======================
-
-Horizon keeps track of changes to the environment by incrementing an
-``environment_version`` integer at the top of ``run_tests.sh``.
-
-If you do anything which changes the environment (adding new dependencies
-or renaming directories are both great examples) be sure to increment the
-``environment_version`` counter as well.
diff --git a/doc/source/ref/tables.rst b/doc/source/ref/tables.rst
deleted file mode 100644
index 4b74d5e3..00000000
--- a/doc/source/ref/tables.rst
+++ /dev/null
@@ -1,82 +0,0 @@
-==================
-Horizon DataTables
-==================
-
-.. module:: horizon.tables
-
-Horizon includes a componentized API for programmatically creating tables
-in the UI. Why would you want this? It means that every table renders
-correctly and consistently, table- and row-level actions all have a consistent
-API and appearance, and generally you don't have to reinvent the wheel or
-copy-and-paste every time you need a new table!
-
-DataTable
-=========
-
-The core class which defines the high-level structure of the table being
-represented. Example::
-
- class MyTable(DataTable):
- name = Column('name')
- email = Column('email')
-
- class Meta:
- name = "my_table"
- table_actions = (MyAction, MyOtherAction)
- row_actions - (MyAction)
-
-A full reference is included below:
-
-.. autoclass:: DataTable
- :members:
-
-DataTable Options
-=================
-
-The following options can be defined in a ``Meta`` class inside a
-:class:`.DataTable` class. Example::
-
- class MyTable(DataTable):
- class Meta:
- name = "my_table"
- verbose_name = "My Table"
-
-.. autoclass:: horizon.tables.base.DataTableOptions
- :members:
-
-Table Components
-================
-
-.. autoclass:: Column
- :members:
-
-.. autoclass:: Row
- :members:
-
-Actions
-=======
-
-.. autoclass:: Action
- :members:
-
-.. autoclass:: LinkAction
- :members:
-
-.. autoclass:: FilterAction
- :members:
-
-.. autoclass:: BatchAction
- :members:
-
-.. autoclass:: DeleteAction
- :members:
-
-Class-Based Views
-=================
-
-Several class-based views are provided to make working with DataTables
-easier in your UI.
-
-.. autoclass:: DataTableView
-
-.. autoclass:: MultiTableView
diff --git a/doc/source/ref/tabs.rst b/doc/source/ref/tabs.rst
deleted file mode 100644
index 807385ca..00000000
--- a/doc/source/ref/tabs.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-==========================
-Horizon Tabs and TabGroups
-==========================
-
-.. module:: horizon.tabs
-
-Horizon includes a set of reusable components for programmatically
-building tabbed interfaces with fancy features like dynamic AJAX loading
-and nearly effortless templating and styling.
-
-Tab Groups
-==========
-
-For any tabbed interface, your fundamental element is the tab group which
-contains all your tabs. This class provides a dead-simple API for building
-tab groups and encapsulates all the necessary logic behind the scenes.
-
-.. autoclass:: TabGroup
- :members:
-
-Tabs
-====
-
-The tab itself is the discrete unit for a tab group, representing one
-view of data.
-
-.. autoclass:: Tab
- :members:
-
-.. autoclass:: TableTab
- :members:
-
-
-
-TabView
-=======
-
-There is also a useful and simple generic class-based view for handling
-the display of a :class:`~horizon.tabs.TabGroup` class.
-
-.. autoclass:: TabView
- :members:
-
-.. autoclass:: TabbedTableView
- :members:
diff --git a/doc/source/ref/test.rst b/doc/source/ref/test.rst
deleted file mode 100644
index 79a4bc1c..00000000
--- a/doc/source/ref/test.rst
+++ /dev/null
@@ -1,25 +0,0 @@
-========================
-Horizon TestCase Classes
-========================
-
-.. module:: horizon.test.helpers
-
-Horizon provides a base test case class which provides several useful
-pre-prepared attributes for testing Horizon components.
-
-.. autoclass:: TestCase
- :members:
-
-.. module :: openstack_dashboard.test.helpers
-
-The OpenStack Dashboard also provides test case classes for greater
-ease-of-use when testing APIs and OpenStack-specific auth scenarios.
-
-.. autoclass:: TestCase
- :members:
-
-.. autoclass:: APITestCase
- :members:
-
-.. autoclass:: BaseAdminViewTests
- :members:
diff --git a/doc/source/ref/workflows.rst b/doc/source/ref/workflows.rst
deleted file mode 100644
index c4077667..00000000
--- a/doc/source/ref/workflows.rst
+++ /dev/null
@@ -1,33 +0,0 @@
-=================
-Horizon Workflows
-=================
-
-.. module:: horizon.workflows
-
-One of the most challenging aspects of building a compelling user experience
-is crafting complex multi-part workflows. Horizon's ``workflows`` module
-aims to bring that capability within everyday reach.
-
-Workflows
-=========
-
-.. autoclass:: Workflow
- :members:
-
-Steps
-=====
-
-.. autoclass:: Step
- :members:
-
-Actions
-=======
-
-.. autoclass:: Action
- :members:
-
-WorkflowView
-============
-
-.. autoclass:: WorkflowView
- :members:
diff --git a/doc/source/releases/2012_1.rst b/doc/source/releases/2012_1.rst
deleted file mode 100644
index e024bf41..00000000
--- a/doc/source/releases/2012_1.rst
+++ /dev/null
@@ -1,148 +0,0 @@
-======================
-Horizon 2012.1 "Essex"
-======================
-
-Release Overview
-================
-
-During the Essex release cycle, Horizon underwent a significant set of internal
-changes to allow extensibility and customization while also adding a significant
-number of new features and bringing much greater stability to every interaction
-with the underlying components.
-
-Highlights
-==========
-
-Extensibility
--------------
-
-Making Horizon extensible for third-party developers was one of the core
-goals for the Essex release cycle. Massive strides have been made to allow
-for the addition of new "plug-in" components and customization of OpenStack
-Dashboard deployments.
-
-To support this extensability, all the components used to build on Horizon's
-interface are now modular and reusable. Horizon's own dashboards use these
-components, and they have all been built with third-party developers in mind.
-Some of the main components are listed below.
-
-Dashboards and Panels
-~~~~~~~~~~~~~~~~~~~~~
-
-Horizon's structure has been divided into logical groupings called dashboards
-and panels. Horizon's classes representing these concepts handle all the
-structural concerns associated with building a complete user interface
-(navigation, access control, url structure, etc.).
-
-Data Tables
-~~~~~~~~~~~
-
-One of the most common activities in a dashboard user interface is simply
-displaying a list of resources or data and allowing the user to take actions on
-that data. To this end, Horizon abstracted the commonalities of this task into a
-reusable set of classes which allow developers to programmatically create
-displays and interactions for their data with minimal effort and zero
-boilerplate.
-
-Tabs and TabGroups
-~~~~~~~~~~~~~~~~~~
-
-Another extremely common user-interface element is the use of "tabs" to break
-down discrete groups of data into manageable chunks. Since these tabs often
-encompasse vastly different data, may have completely different access
-restrictions, and may sometimes be better-off being loaded dynamically rather
-than with the initial page load, Horizon includes tab and tab group classes for
-constructing these interfaces elegently and with no knowledge of the HTML, CSS
-or JavaScript involved.
-
-Nova Features
--------------
-
-Support for Nova's features has been greatly improved in Essex:
-
-* Support for Nova volumes, including:
- * Volumes creation and management.
- * Volume snapshots.
- * Realtime AJAX updating for volumes in transition states.
-* Improved Nova instance display and interactions, including:
- * Launching instances from volumes.
- * Pausing/suspending instances.
- * Displaying instance power states.
- * Realtime AJAX updating for instances in transition states.
-* Support for managing Floating IP address pools.
-* New instance and volume detail views.
-
-Settings
---------
-
-A new "Settings" area was added that offers several userful functions:
-
-* EC2 credentials download.
-* OpenStack RC file download.
-* User language preference customization.
-
-User Experience Improvements
-----------------------------
-
-* Support for batch actions on multiple resources (e.g. terminating multiple
- instances at once).
-* Modal interactions throughout the entire UI.
-* AJAX form submission for in-place validation.
-* Improved in-context help for forms (tooltips and validation messages).
-
-
-Community
----------
-
-* Creation and publication of a set of Human Interface Guidelines (HIG).
-* Copious amounts of documentation for developers.
-
-Under The Hood
---------------
-
-* Internationalization fully enabled, with all strings marked for translation.
-* Client library changes:
- * Full migration to python-novaclient from the deprecated openstackx library.
- * Migration to python-keystoneclient from the deprecated keystone portion
- of the python-novaclient library.
-* Client-side templating capabilities for more easily creating dynamic
- interactions.
-* Frontend overhaul to use the Bootstrap CSS/JS framework.
-* Centralized error handling for vastly improved stability/reliability
- across APIs/clients.
-* Completely revamped test suite with comprehensive test data.
-* Forward-compatibility with Django 1.4 and the option of cookie-based sessions.
-
-Known Issues and Limitations
-============================
-
-Quantum
--------
-
-Quantum support has been removed from Horizon for the Essex release. It will be
-restored in Folsom in conjunction with Quantum's first release as a core
-OpenStack project.
-
-Keystone
---------
-
-Due to the mechanisms by which Keystone determines "admin"-ness for a user, an
-admin user interacting with the "Project" dashboard may see some inconsistent
-behavior such as all resources being listed instead of only those belonging to
-that project, or only being able to return to the "Admin" dashboard while
-accessing certain projects.
-
-Exceptions during customization
--------------------------------
-
-Exceptions raised while overriding built-in Horizon behavior via the
-"customization_module" setting may trigger a bug in the error handling
-which will mask the original exception.
-
-Backwards Compatibility
-=======================
-
-The Essex Horizon release is only partially backwards-compatible with Diablo
-OpenStack components. While it is largely possible to log in and interact, many
-functions in Nova, Glance and Keystone changed too substantially in Essex to
-maintain full compatibliity.
diff --git a/doc/source/releases/2012_2.rst b/doc/source/releases/2012_2.rst
deleted file mode 100644
index 0ff3e5c8..00000000
--- a/doc/source/releases/2012_2.rst
+++ /dev/null
@@ -1,159 +0,0 @@
-=======================
-Horizon 2012.2 "Folsom"
-=======================
-
-Release Overview
-================
-
-The Folsom release cycle brought several major advances to Horizon's user
-experience while also reintroducing Quantum networking as a core piece
-of the OpenStack Dashboard.
-
-Highlights
-==========
-
-Networking (Quantum)
---------------------
-
-With Quantum being a core project for the Folsom release, we worked closely
-with the Quantum team to bring networking support back into Horizon. This
-appears in two primary places: the Networks panel in both the Project and
-Admin dashboards, and the Network tab in the Launch Instance workflow. Expect
-further improvements in these areas as Quantum continues to mature and more
-users adopt this model of virtual network management.
-
-User Experience
----------------
-
-Workflows
-~~~~~~~~~
-
-By far the biggest UI/UX change in the Folsom release is the introduction of
-programmatic workflows. These components allow developers to create concise
-interactions that combine discrete tasks spanning multiple services and
-resources in a user-friendly way and with minimal boilerplate code. Within
-a workflow, related objects can also be dynamically created so users don't lose
-their place when they realize the item they wanted isn't currently available.
-Look for examples of these workflows in Launch Instance, Associate Floating IP,
-and Create/Edit Project.
-
-Resource Browser
-~~~~~~~~~~~~~~~~
-
-Another cool new component is an interface designed for "browsing" resources
-which are nested under a parent resource. The object store (Swift) is a prime
-example of this. Now there is a consistent top-level navigation for containers
-on the left-hand pane of the "browser" while the right-hand pane lets you
-explore within those containers and sub-folders.
-
-User Experience Improvements
-----------------------------
-
-* Timezone support is now enabled. You can select your preferred timezone
- in the User Settings panel.
-
-Community
----------
-
-* Third-party developers who wish to build on Horizon can get started much
- faster using the new dashboard and panel templates. See the docs on
- `creating a dashboard`_ and `creating a panel`_ for more information.
-
-* A `thorough set of documentation`_ for developers on how to go about
- internationalizing, localizing and translating OpenStack projects
- is now available.
-
-.. _creating a dashboard: http://docs.openstack.org/developer/horizon/topics/tutorial.html#creating-a-dashboard
-.. _creating a panel: http://docs.openstack.org/developer/horizon/topics/tutorial.html#creating-a-panel
-.. _thorough set of documentation: http://wiki.openstack.org/Translations
-
-Under The Hood
---------------
-
-* The python-swiftclient library and python-cinderclient libraries are now
- used under the hood instead of cloudfiles and python-novaclient respectively.
-
-* Internationalization of client-side JavaScript is now possible in addition
- to server-side Python code.
-
-* Keystone authentication is now handled by a proper pluggable Django
- authentication backend, offering significantly better and more reliable
- security for Horizon.
-
-Other Improvements and Fixes
-----------------------------
-
-Some of the general areas of improvement include:
-
-* Images can now be added to Glance by providing a URL for Glance to download
- the image data from.
-
-* Quotas are now displayed dynamically throughout the Project dashboard.
-
-* API endpoints are now displayed on the OpenStack RC File panel so they
- can be organically discovered by an end-user.
-
-* DataTables now support a summation row at the bottom of the table.
-
-* Better cross-browser support (Safari and IE particularly).
-
-* Fewer API calls to OpenStack endpoints (improves performance).
-
-* Better validation of what actions are permitted when.
-
-* Improved error handling and error messages.
-
-Known Issues and Limitations
-============================
-
-Floating IPs and Quantum
-------------------------
-
-Due to the very late addition of floating IP support in Quantum, Nova's
-integration there is lacking, so floating IP-related API calls to Nova will
-fail when your OpenStack deployment uses Quantum for networking. This means
-that Horizon actions such as "allocate" and "associate" floating IPs will
-not work either since they rely on the underlying APIs.
-
-Pagination
-----------
-
-A number of the "index" pages don't fully work with API pagination yet,
-causing them to only display the first chunk of results returned by the API.
-This number is often 1000 (as in the case of novaclient results), but does vary
-somewhat.
-
-Deleting large numbers of resources simultaneously
---------------------------------------------------
-
-Using the "select all" checkbox to delete large numbers of resources via the
-API can cause network timeouts (depending on configuration). This is
-due to the APIs not supporting bulk-deletion natively, and consequently Horizon
-has to send requests to delete each resource individually behind the scenes.
-
-Backwards Compatibility
-=======================
-
-The Folsom Horizon release should be fully-compatible with both Folsom and
-Essex versions of the rest of the OpenStack core projects (Nova, Swift, etc.).
-While some features work significantly better with an all-Folsom stack due
-to bugfixes, etc. in underlying services, there should not be any limitations
-on what will or will not function. (Note: Quantum was not a core OpenStack
-project in Essex, and thus this statement does not apply to network management.)
-
-In terms of APIs provided for extending Horizon, there are a handful of
-backwards-incompatible changes that were made:
-
-* The ``can_haz`` and ``can_haz_list`` template filters have been renamed
- to ``has_permissions`` and ``has_permissions_on_list`` respectively.
-
-* The dashboard-specific ``base.html`` templates (e.g. ``nova/base.html``,
- ``syspanel/base.html``, etc.) have been removed in favor of a single
- ``base.html`` template.
-
-* In conjunction with the previous item, the dashboard-specific template blocks
- (e.g. ``nova_main``, ``syspanel_main``, etc.) have been removed in favor of
- a single ``main`` template block.
-
-Overall, though, great effort has been made to maintain compatibility for
-third-party developers who may have built on Horizon so far. \ No newline at end of file
diff --git a/doc/source/releases/2013_1.rst b/doc/source/releases/2013_1.rst
deleted file mode 100644
index 330a6ae2..00000000
--- a/doc/source/releases/2013_1.rst
+++ /dev/null
@@ -1,274 +0,0 @@
-========================
-Horizon 2013.1 "Grizzly"
-========================
-
-Release Overview
-================
-
-The Grizzly release cycle saw sweeping improvements to overall user experience,
-huge stability improvements, lots of new networking, instance management and
-image management features, a long-needed architectural clarification, and big
-increases in community engagement! Read on to get the specifics.
-
-Highlights
-==========
-
-New Features
-------------
-
-Networking
-~~~~~~~~~~
-
-Quantum added a huge number of new features in Grizzly, including L3 support
-(routers), load balancers, network topology infographics, better compatibility
-with Nova networking APIs (VNIC ordering when launching an instance; security
-groups and floating IP integration) and vastly improved informational displays.
-
-Direct Image Upload To Glance
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It is now possible (though there are numerous deployment/security implications)
-to upload an image file directly from a user's hard disk to Glance through
-Horizon. For multi-GB images it is still strongly recommended that the upload
-be done using the Glance CLI. Further improvements to this feature will come in
-future releases.
-
-Flavor Extra Specs Support
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In Folsom, Nova added support for "extra specs" on flavors--additional metadata
-which custom schedulers could use for appropriately scheduling instances. As of
-the Grizzly release, Horizon now supports reading and writing that data on any
-flavor.
-
-Migrate Instance
-~~~~~~~~~~~~~~~~
-
-Administrators now have the ability to migrate an instance off of its current
-host via the Admin dashboard's Instances panel.
-
-
-User Experience Improvements
-----------------------------
-
-"Not Authorized" & Being Logged Out
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A shocking number of the problems first-time deployers of OpenStack have can be
-summarized as "I thought I set everything up, then I tried to log into the
-dashboard and I was immediately logged back out." The root cause of this was
-that in an effort to be as secure as possible any 401 or 403 response from
-any service API was being treated the same as if it was an attempt to access
-an unauthorized portion of Horizon, and the user was summarily logged out with
-little to no information as to why.
-
-In Grizzly we have instead chosen to improve this by treating service API
-401 and 403 errors as slightly less severe than unauthorized access attempts
-to resitricted areas of Horizon. The reason for this is threefold:
-
-#. For a non-malicious user these errors are almost 100% the result of
- misconfiguration and this makes debugging possible.
-#. A malicious user can make the exact same "unauthorized" requests via the
- CLI as they can via the dashboard; no special privileges are granted.
-#. API errors are generated by external systems not under the purview of our
- project and while we should attempt to respect and take appropriate action
- on those errors, we should not do anything drastic or even potentially
- destructive because of them.
-
-Going forward the user will not be logged out, but no information will be
-populated on the page and they will be presented with error messages informing
-them that they are unauthorized for the data they attempted to access.
-
-Reorganizations
-~~~~~~~~~~~~~~~
-
-A couple of long-standing user confusions were fixed in Grizzly.
-
-First off, the API Access panel (containing a user's API endpoints, rc files,
-and EC2 credentials) was moved from Settings to the Access & Security section
-of the Project dashboard.
-
-Second, the Default Quotas and Services panels (which were both strictly
-informational) were combined into tabs in a single System Info panel to make
-it clear that these panels are thematically related, and to create a home for
-informational-only displays like these.
-
-One-click Floating IP Management
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A common complaint from users was that associating a floating IP to an
-instance involved numerous clicks and form selections for something that
-the majority of users had no knowledge of and didn't care about. As such, a
-one-click "simple" floating IP association option has been created. For
-deployments which only have a single floating IP pool, this allows users to
-ignore explicit floating IP management and just click a button to associate
-or disassociate a floating IP with an instance.
-
-Organized Images
-~~~~~~~~~~~~~~~~
-
-The Images table now has a new feature: predefined filters for seeing your own
-images, images that have been shared with you, or public images. This makes
-finding the image you're looking for a great deal easier and more pleasant.
-
-Security Group Rule Editing Improvements
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The security group rule editing experience has always been inherently very
-complicated simply given the number of options and the very technical terms
-involved. Moreover, the combined table-plus-form approach the OpenStack
-Dashboard had taken only made the UX more frustrating for an already difficult
-area.
-
-In Grizzly this has all been reworked to be signficantly simpler, and to
-provide as much contextual help and streamlining as possible.
-
-Icons!
-~~~~~~
-
-In an effort to make the dashboard more at-a-glance usable, we've added icons
-to most of the common action buttons throughout the dashboard.
-
-"More Actions", More Better
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Lots of feedback came in that the "more actions" dropdown menu (for tables with
-numerous actions available on each row) was confusing to new users and/or
-difficult to click.
-
-We've now improved it so that the button to open the menu is clearly labeled
-and the hitbox for clicking it is significantly larger.
-
-
-Community
----------
-
-Docs, docs, and more docs!
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Large amounts of new documentation was added during the Grizzly cycle, most
-notably are sections documenting: all of the available settings for Horizon and
-the OpenStack Dashboard; security and deployment considerations; and deeper
-guides on customizing the OpenStack Dashboard.
-
-IRC Meeting
-~~~~~~~~~~~
-
-During the Grizzly cycle we started holding a weekly project meeting on IRC.
-This has been extremely beneficial for the growth and progress of the project.
-Check out the `OpenStack Meetings wiki page`_ for specifics.
-
-.. _Openstack Meetings wiki page: https://wiki.openstack.org/wiki/Meetings#Horizon_team_meeting
-
-
-Under The Hood
---------------
-
-Legacy Dashboard Names & Code Separation
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Very early in the Grizzly cycle we took the opportunity to do some longstanding
-cleanup and refactoring work. The "nova" dashboard was renamed to "project" and
-the "syspanel" dashboard was renamed to "admin" to better reflect their
-respective purposes.
-
-Moreover, a better separation was created between code related to the core
-Horizon framework code (which is not related to OpenStack specifically) and
-the OpenStack Dashboard code. At this point *all* code related to OpenStack
-lives in the OpenStack Dashboard directory, while the Horizon framework is
-completely agnostic and is a reusable Django app.
-
-Object Storage Delimiters and Pseudo-folder Objects
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When Horizon's object storage interface was first added, Swift's documentation
-recommended adding 0-byte objects with a special content type to denote
-pseudo-folders within a container. They have since decided that this is not the
-recommended practice, and that pseudo-folders should only be demarcated by
-a delimiting character (usually "/") in the object name.
-
-Horizon has been updated under the hood to use this method, which should bring
-it better into line with how most deployments are using their object storage.
-
-
-Other Improvements and Fixes
-----------------------------
-
-* Support for Keystone's PKI tokens.
-
-* Flavor editing was made significantly more stable.
-
-* Security groups can be added to a running instance.
-
-* Volume quotas are handled by the appopriate service depending on whether
- or not Cinder is enabled.
-
-* Password confirmation boxes are now validated for matching passwords on
- the client side for more immediate feedback.
-
-* Numerous fixes to display more and better information for instances and
- volumes in their overview pages.
-
-* Improved unicode support for the Object Storage panels.
-
-* Logout now attempts to delete the token(s) associated with the current
- session to avoid replay attacks, etc.
-
-* Various fixes for browser compatibility and rendering.
-
-* Many, many other bugfixes and improvements. Check out Launchpad for the full
- list of what went on in Grizzly.
-
-
-Known Issues and Limitations
-============================
-
-Editing a Flavor Which Results In An API Error Will Delete The Flavor
----------------------------------------------------------------------
-
-Due to the way that Nova handles flavor editing/replacement it is necessary
-to delete the old flavor before creating the replacement flavor. As such,
-if an API error occurs while creating the replacement it is possible to
-lose the old flavor without the new one being created.
-
-Creating Rich Network Topologies
---------------------------------
-
-Due to several Quantum features landing very late in the Grizzly cycle, it
-is not possible to create particularly complex networking configurations
-through the OpenStack Dashboard. These features will continue to grow
-throughout future releases.
-
-Loadbalancer Feature
---------------------
-
-The Loadbalancer feature landed in the 11th hour for both Quantum and Horizon
-and, though we did our best to test it, may still contain undiscovered bugs. It
-is best considered a "beta" or "experimental" feature for the Grizzly release.
-
-Quantum Brocade Plugin Not Compatible
--------------------------------------
-
-The Brocade plugin for Quantum does not support key features of the floating
-IP addresses API which are considered central to Horizon's functionality. As
-such, it is not compatible with the Grizzly release's Quantum integration.
-
-Deleting large numbers of resources simultaneously
---------------------------------------------------
-
-Using the "select all" checkbox to delete large numbers of resources via the
-API can cause network timeouts (depending on configuration). This is
-due to the APIs not supporting bulk-deletion natively, and consequently Horizon
-has to send requests to delete each resource individually behind the scenes.
-
-Backwards Compatibility
-=======================
-
-The Grizzly Horizon release should be fully compatible with both Grizzly and
-Folsom versions of the rest of the OpenStack core projects (Nova, Swift, etc.).
-While some features work significantly better with an all-Grizzly stack due
-to bugfixes, etc. in underlying services, there should not be limitations
-on what will or will not function.
-
-Overall, great effort has been made to maintain compatibility for
-third-party developers who may have built on Horizon so far.
diff --git a/doc/source/testing.rst b/doc/source/testing.rst
deleted file mode 100644
index d9362327..00000000
--- a/doc/source/testing.rst
+++ /dev/null
@@ -1,41 +0,0 @@
-=======================
-Horizon's tests and you
-=======================
-
-How to run the tests
-====================
-
-Because Horizon is composed of both the ``horizon`` app and the
-``openstack-dashboard`` reference project, there are in fact two sets of unit
-tests. While they can be run individually without problem, there is an easier
-way:
-
-Included at the root of the repository is the ``run_tests.sh`` script
-which invokes both sets of tests, and optionally generates analyses on both
-components in the process. This script is what what Jenkins uses to verify the
-stability of the project, so you should make sure you run it and it passes
-before you submit any pull requests/patches.
-
-To run the tests::
-
- $ ./run_tests.sh
-
-It's also possible to :doc:`run a subset of unit tests<ref/run_tests>`.
-
-.. seealso::
-
- :doc:`ref/run_tests`
- Full reference for the ``run_tests.sh`` script.
-
-Writing tests
-=============
-
-Horizon uses Django's unit test machinery (which extends Python's ``unittest2``
-library) as the core of its test suite. As such, all tests for the Python code
-should be written as unit tests. No doctests please.
-
-In general new code without unit tests will not be accepted, and every bugfix
-*must* include a regression test.
-
-For a much more in-depth discussion of testing, see the :doc:`testing topic
-guide </topics/testing>`.
diff --git a/doc/source/topics/customizing.rst b/doc/source/topics/customizing.rst
deleted file mode 100644
index 474f778e..00000000
--- a/doc/source/topics/customizing.rst
+++ /dev/null
@@ -1,137 +0,0 @@
-===================
-Customizing Horizon
-===================
-
-Changing the Site Title
-=======================
-
-The OpenStack Dashboard Site Title branding (i.e. "**OpenStack** Dashboard")
-can be overwritten by adding the attribute ``SITE_BRANDING``
-to ``local_settings.py`` with the value being the desired name.
-
-The file ``local_settings.py`` can be found at the Horizon directory path of
-``horizon/openstack-dashboard/local/local_settings.py``.
-
-Changing the Logo
-=================
-
-The OpenStack Logo is pulled in through ``style.css``::
-
- #splash .modal {
- background: #fff url(../images/logo.png) no-repeat center 35px;
-
- h1.brand a {
- background: url(../images/logo.png) top left no-repeat;
-
-To override the OpenStack Logo image, replace the image at the directory path
-``horizon/openstack-dashboard/dashboard/static/dashboard/images/logo.png``.
-
-The dimensions should be ``width: 108px, height: 121px``.
-
-Modifying Existing Dashboards and Panels
-========================================
-
-If you wish to alter dashboards or panels which are not part of your codebase,
-you can specify a custom python module which will be loaded after the entire
-Horizon site has been initialized, but prior to the URLconf construction.
-This allows for common site-customization requirements such as:
-
-* Registering or unregistering panels from an existing dashboard.
-* Changing the names of dashboards and panels.
-* Re-ordering panels within a dashboard or panel group.
-
-To specify the python module containing your modifications, add the key
-``customization_module`` to your ``settings.HORIZON_CONFIG`` dictionary.
-The value should be a string containing the path to your module in dotted
-python path notation. Example::
-
- HORIZON_CONFIG = {
- "customization_module": "my_project.overrides"
- }
-
-You can do essentially anything you like in the customization module. For
-example, you could change the name of a panel::
-
- from django.utils.translation import ugettext_lazy as _
-
- import horizon
-
- # Rename "User Settings" to "User Options"
- settings = horizon.get_dashboard("settings")
- user_panel = settings.get_panel("user")
- user_panel.name = _("User Options")
-
-Or get the instances panel::
-
- projects_dashboard = horizon.get_dashboard("project")
- instances_panel = projects_dashboard.get_panel("instances")
-
-And limit access to users with the Keystone Admin role::
-
- permissions = list(getattr(instances_panel, 'permissions', []))
- permissions.append('openstack.roles.admin')
- instances_panel.permissions = tuple(permissions)
-
-Or just remove it entirely::
-
- projects_dashboard.unregister(instances_panel.__class__)
-
-.. NOTE::
-
- ``my_project.overrides`` needs to be importable by the python process running
- Horizon.
- If your module is not installed as a system-wide python package,
- you can either make it installable (e.g., with a setup.py)
- or you can adjust the python path used by your WSGI server to include its location.
-
- Probably the easiest way is to add a ``python-path`` argument to
- the ``WSGIDaemonProcess`` line in Apache's Horizon config.
-
- Assuming your ``my_project`` module lives in ``/opt/python/my_project``,
- you'd make it look like the following::
-
- WSGIDaemonProcess [... existing options ...] python-path=/opt/python
-
-
-Button Icons
-============
-
-Horizon provides hooks for customizing the look and feel of each class of
-button on the site. The following classes are used to identify each type of
-button:
-
-* Generic Classes
- * btn-search
- * btn-delete
- * btn-upload
- * btn-download
- * btn-create
- * btn-edit
- * btn-list
- * btn-copy
- * btn-camera
- * btn-stats
- * btn-enable
- * btn-disable
-
-* Floating IP-specific Classes
- * btn-allocate
- * btn-release
- * btn-associate
- * btn-disassociate
-
-* Instance-specific Classes
- * btn-launch
- * btn-terminate
- * btn-reboot
- * btn-pause
- * btn-suspend
- * btn-console
- * btn-log
-
-* Volume-specific classes
- * btn-detach
-
-Additionally, the site-wide default button classes can be configured by
-setting ``ACTION_CSS_CLASSES`` to a tuple of the classes you wish to appear
-on all action buttons in your ``local_settings.py`` file.
diff --git a/doc/source/topics/deployment.rst b/doc/source/topics/deployment.rst
deleted file mode 100644
index f40913d6..00000000
--- a/doc/source/topics/deployment.rst
+++ /dev/null
@@ -1,217 +0,0 @@
-=================
-Deploying Horizon
-=================
-
-This guide aims to cover some common questions, concerns and pitfalls you
-may encounter when deploying Horizon in a production environment.
-
-.. seealso:: :doc:`settings`
-
-.. note::
-
- The Service Catalog returned by the Identity Service after a user
- has successfully authenticated determines the dashboards and panels
- that will be available within the OpenStack Dashboard. If you are not
- seeing a particular service you expected (e.g. Object Storage/Swift or
- Networking/Neutron) make sure your Service Catalog is configured correctly.
-
- Prior to the Essex release of Horizon these features were controlled by
- individual settings in the ``local_settings.py`` file. This code has been
- long-since removed and those pre-Essex settings have no impact now.
-
-Configure Your Identity Service Host
-====================================
-
-The one thing you *must* do in order to run Horizon is to specify the
-host for your OpenStack Identity Service endpoint. To do this, set the value
-of the ``OPENSTACK_HOST`` settings in your ``local_settings.py`` file.
-
-Logging
-=======
-
-Logging is an important concern for production deployments, and the intricacies
-of good logging configuration go far beyond what can be covered here. However
-there are a few points worth noting about the logging included with Horizon,
-how to customize it, and where other components may take over:
-
-* Horizon's logging uses Django's logging configuration mechanism, which
- can be customized in your ``local_settings.py`` file through the
- ``LOGGING`` dictionary.
-* Horizon's default logging example sets the log level to ``"INFO"``, which is
- a reasonable choice for production deployments. For development, however,
- you may want to change the log level to ``"DEBUG"``.
-* Horizon also uses a number of 3rd-party clients which log separately. The
- log level for these can still be controlled through Horizon's ``LOGGING``
- config, however behaviors may vary beyond Horizon's control.
-* For more information regarding configuring logging in Horizon, please
- read the `Django logging directive`_ and the `Python logging directive`_
- documentation. Horizon is built on Python and Django.
-
-.. _Django logging directive: https://docs.djangoproject.com/en/1.5/topics/logging
-.. _Python logging directive: http://docs.python.org/2/library/logging.html
-
-.. warning::
-
- At this time there is `a known bug in python-keystoneclient`_ where it will
- log the complete request body of any request sent to Keystone through it
- (including logging passwords in plain text) when the log level is set to
- ``"DEBUG"``. If this behavior is not desired, make sure your log level is
- ``"INFO"`` or higher.
-
-.. _a known bug in python-keystoneclient: https://bugs.launchpad.net/keystone/+bug/1004114
-
-File Uploads
-============
-
-Horizon allows users to upload files via their web browser to other OpenStack
-services such as Glance and Swift. Files uploaded through this mechanism are
-first stored on the Horizon server before being forwarded on - files are not
-uploaded directly or streamed as Horizon receives them. As Horizon itself does
-not impose any restrictions on the size of file uploads, production deployments
-will want to consider configuring their server hosting the Horizon application
-to enforce such a limit to prevent large uploads exhausting system resources
-and disrupting services. Deployments using Apache2 can use the
-`LimitRequestBody directive`_ to achieve this.
-
-Uploads to the Glance image store service tend to be particularly large - in
-the order of hundreds of megabytes to multiple gigabytes. Deployments are able
-to disable the ability to upload images through Horizon by setting
-``HORIZON_IMAGES_ALLOW_UPLOAD`` to ``False`` in your ``local_settings.py``
-file.
-
- .. _LimitRequestBody directive: http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestbody
-
-Session Storage
-===============
-
-Horizon uses `Django's sessions framework`_ for handling user session data;
-however that's not the end of the story. There are numerous session backends
-available, which are controlled through the ``SESSION_ENGINE`` setting in
-your ``local_settings.py`` file. What follows is a quick discussion of the
-pros and cons of each of the common options as they pertain to deploying
-Horizon specifically.
-
-.. _Django's sessions framework: https://docs.djangoproject.com/en/dev/topics/http/sessions/
-
-Local Memory Cache
-------------------
-
-Enabled by::
-
- SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
- CACHES = {
- 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
- }
-
-Local memory storage is the quickest and easiest session backend to set up,
-as it has no external dependencies whatsoever. However, it has two significant
-drawbacks:
-
- * No shared storage across processes or workers.
- * No persistence after a process terminates.
-
-The local memory backend is enabled as the default for Horizon solely because
-it has no dependencies. It is not recommended for production use, or even for
-serious development work. For better options, read on.
-
-Memcached
----------
-
-Enabled by::
-
- SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
- CACHES = {
- 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache'
- 'LOCATION': 'my_memcached_host:11211',
- }
-
-External caching using an application such as memcached offers persistence
-and shared storage, and can be very useful for small-scale deployment and/or
-development. However, for distributed and high-availability scenarios
-memcached has inherent problems which are beyond the scope of this
-documentation.
-
-Memcached is an extremely fast and efficient cache backend for cases where it
-fits the deployment need. But it's not appropriate for all scenarios.
-
-Requirements:
-
- * Memcached service running and accessible.
- * Python memcached module installed.
-
-Database
---------
-
-Enabled by::
-
- SESSION_ENGINE = 'django.core.cache.backends.db.DatabaseCache'
- DATABASES = {
- 'default': {
- # Databe configuration here
- }
- }
-
-Database-backed sessions are scalable (using an appropriate database strategy),
-persistent, and can be made high-concurrency and highly-available.
-
-The downside to this approach is that database-backed sessions are one of the
-slower session storages, and incur a high overhead under heavy usage. Proper
-configuration of your database deployment can also be a substantial
-undertaking and is far beyond the scope of this documentation.
-
-Cached Database
----------------
-
-To mitigate the performance issues of database queries, you can also consider
-using Django's ``cached_db`` session backend which utilizes both your database
-and caching infrastructure to perform write-through caching and efficient
-retrieval. You can enable this hybrid setting by configuring both your database
-and cache as discussed above and then using::
-
- SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
-
-Cookies
--------
-
-If you're using Django 1.4 or later, a new session backend is available to you
-which avoids server load and scaling problems: the ``signed_cookies`` backend!
-
-This backend stores session data in a cookie which is stored by the
-user's browser. The backend uses a cryptographic signing technique to ensure
-session data is not tampered with during transport (**this is not the same
-as encryption, session data is still readable by an attacker**).
-
-The pros of this session engine are that it doesn't require any additional
-dependencies or infrastructure overhead, and it scales indefinitely as long
-as the quantity of session data being stored fits into a normal cookie.
-
-The biggest downside is that it places session data into storage on the user's
-machine and transports it over the wire. It also limits the quantity of
-session data which can be stored.
-
-For a thorough discussion of the security implications of this session backend,
-please read the `Django documentation on cookie-based sessions`_.
-
-.. _Django documentation on cookie-based sessions: https://docs.djangoproject.com/en/dev/topics/http/sessions/#using-cookie-based-sessions
-
-Secure Site Recommendations
----------------------------
-
-When implementing Horizon for public usage, with the website served through
-HTTPS, it is recommended that the following settings are applied.
-
-To help protect the session cookies from `cross-site scripting`_, add the
-following to ``local_settings.py`` :
-
- CSRF_COOKIE_SECURE = True
- SESSION_COOKIE_SECURE = True
- SESSION_COOKIE_HTTPONLY = True
-
-Note that the CSRF_COOKIE_SECURE option is only available from Django 1.4. It
-does no harm to have the setting in earlier versions, but it does not take effect.
-
-You can also disable `browser autocompletion`_ for the authentication form by
-changing the ``password_autocomplete`` attribute to ``off`` in ``horizon/conf/default.py``
-
-.. _cross-site scripting: https://www.owasp.org/index.php/HttpOnly
-.. _browser autocompletion: https://wiki.mozilla.org/The_autocomplete_attribute_and_web_documents_using_XHTML
diff --git a/doc/source/topics/settings.rst b/doc/source/topics/settings.rst
deleted file mode 100644
index a1777c11..00000000
--- a/doc/source/topics/settings.rst
+++ /dev/null
@@ -1,294 +0,0 @@
-==================================
-Horizon Settings and Configuration
-==================================
-
-Introduction
-============
-
-Horizon's settings tend to fall into three categories:
-
-* Horizon configuration options (contained in the ``HORIZON_CONFIG`` dict)
- which are not OpenStack-specific and pertain only to the core framework.
-* OpenStack-related settings which pertain to other projects/services and
- are generally prefixed with ``OPENSTACK_`` in the settings file.
-* Django settings (including common plugins like ``django-compressor``) which
- can be (and should be) read about in their respective documentation.
-
-What follows is an overview of the Horizon and OpenStack-specific settings
-and a few notes on the Django-related settings.
-
-.. note::
-
- Prior to the Essex release of Horizon there were settings which controlled
- whether features such as Object Storage/Swift or Networking/Neutron would be
- enabled in the OpenStack Dashboard. This code has beenlong-since removed and
- those pre-Essex settings have no impact now.
-
- In Essex and later, the Service Catalog returned by the Identity Service
- after a user has successfully authenticated determines the dashboards and
- panels that will be available within the OpenStack Dashboard. If you are not
- seeing a particular service you expected make sure your Service Catalog is
- configured correctly.
-
-Horizon Settings
-================
-
-The following options are available in order to configure/customize the
-behavior of your Horizon installation. All of them are contained in the
-``HORIZON_CONFIG`` dictionary.
-
-``dashboards``
---------------
-
-Default: ``None``
-
-A list containing the slugs of any dashboards which should be active in this
-Horizon installation. The dashboards listed must be in a Python module which
-is included in the ``INSTALLED_APPS`` list and on the Python path.
-
-``default_dashboard``
----------------------
-
-Default: ``None``
-
-The slug of the dashboard which should act as the first-run/fallback dashboard
-whenever a user logs in or is otherwise redirected to an ambiguous location.
-
-``user_home``
--------------
-
-Default: ``settings.LOGIN_REDIRECT_URL``
-
-This can be either a literal URL path (such as the default), or Python's
-dotted string notation representing a function which will evaluate what URL
-a user should be redirected to based on the attributes of that user.
-
-``ajax_queue_limit``
---------------------
-
-Default: ``10``
-
-The maximum number of simultaneous AJAX connections the dashboard may try
-to make. This is particularly relevant when monitoring a large number of
-instances, volumes, etc. which are all actively trying to update/change state.
-
-``ajax_poll_interval``
-----------------------
-
-Default: ``2500``
-
-How frequently resources in transition states should be polled for updates,
-expressed in milliseconds.
-
-``help_url``
-------------
-
-Default: None
-
-If provided, a "Help" link will be displayed in the site header which links
-to the value of this settings (ideally a URL containing help information).
-
-``exceptions``
---------------
-
-Default: ``{'unauthorized': [], 'not_found': [], 'recoverable': []}``
-
-A dictionary containing classes of exceptions which Horizon's centralized
-exception handling should be aware of.
-
-``password_validator``
-----------------------
-
-Default: {'regex': '.*', 'help_text': _("Password is not accepted")}
-
-A dictionary containing a regular expression which will be used for password
-validation and help text which will be displayed if the password does not
-pass validation. The help text should describe the password requirements if
-there are any.
-
-This setting allows you to set rules for passwords if your organization
-requires them.
-
-``password_autocomplete``
--------------------------
-
-Default: ``"on"``
-
-Controls whether browser autocompletion should be enabled on the login form.
-Valid values are ``"on"`` and ``"off"``.
-
-``simple_ip_management``
-------------------------
-
-Default: ``True``
-
-Enable or disable simplified floating IP address management.
-
-"Simple" floating IP address management means that the user does not ever have
-to select the specific IP addresses they wish to use, and the process of
-allocating an IP and assigning it to an instance is one-click.
-
-The "advanced" floating IP management allows users to select the floating IP
-pool from which the IP should be allocated and to select a specific IP address
-when associating one with an instance.
-
-
-OpenStack Settings
-==================
-
-The following settings inform the OpenStack Dashboard of information about the
-other OpenStack projects which are part of this cloud and control the behavior
-of specific dashboards, panels, API calls, etc.
-
-``OPENSTACK_HOST``
-------------------
-
-Default: ``"127.0.0.1"``
-
-The hostname of the Keystone server used for authentication if you only have
-one region. This is often the *only* settings that needs to be set for a
-basic deployment.
-
-
-``OPENSTACK_KEYSTONE_URL``
---------------------------
-
-Default: ``"http://%s:5000/v2.0" % OPENSTACK_HOST``
-
-The full URL for the Keystone endpoint used for authentication. Unless you
-are using HTTPS, running your Keystone server on a nonstandard port, or using
-a nonstandard URL scheme you shouldn't need to touch this setting.
-
-``AVAILABLE_REGIONS``
----------------------
-
-Default: ``None``
-
-A tuple of tuples which define multiple regions. The tuple format is
-``('http://{{keystone_host}}:5000/v2.0', '{{region_name}}')``. If any regions
-are specified the login form will have a dropdown selector for authenticating
-to the appropriate region, and there will be a region switcher dropdown in
-the site header when logged in.
-
-If you do not have multiple regions you should use the ``OPENSTACK_HOST`` and
-``OPENSTACK_KEYSTONE_URL`` settings above instead.
-
-``OPENSTACK_KEYSTONE_DEFAULT_ROLE``
------------------------------------
-
-Default: "Member"
-
-The name of the role which will be assigned to a user when added to a project.
-This name must correspond to a role name in Keystone.
-
-``OPENSTACK_SSL_NO_VERIFY``
----------------------------
-
-Default: ``False``
-
-Disable SSL certificate checks in the OpenStack clients (useful for self-signed
-certificates).
-
-``OPENSTACK_KEYSTONE_BACKEND``
-------------------------------
-
-Default: ``{'name': 'native', 'can_edit_user': True, 'can_edit_project': True}``
-
-A dictionary containing settings which can be used to identify the
-capabilities of the auth backend for Keystone.
-
-If Keystone has been configured to use LDAP as the auth backend then set
-``can_edit_user`` and ``can_edit_project`` to ``False`` and name to ``"ldap"``.
-
-
-``OPENSTACK_HYPERVISOR_FEATURES``
----------------------------------
-
-Default: ``{'can_set_mount_point': True, 'can_encrypt_volumes': False}``
-
-A dictionary containing settings which can be used to identify the
-capabilities of the hypervisor for Nova.
-
-Some hypervisors have the ability to set the mount point for volumes attached
-to instances (KVM does not). Setting ``can_set_mount_point`` to ``False`` will
-remove the option to set the mount point from the UI.
-
-In the Havana release, there will be a feature for encrypted volumes
-which will be controlled by the ``can_encrypt_volumes``. Setting it to ``True``
-in the Grizzly release will have no effect.
-
-``OPENSTACK_NEUTRON_NETWORK``
------------------------------
-
-Default: ``{'enable_lb': False}``
-
-A dictionary of settings which can be used to enable optional services provided
-by neutron. Currently only the load balancer service is available.
-
-``OPENSTACK_ENDPOINT_TYPE``
----------------------------
-
-Default: ``"internalURL"``
-
-A string which specifies the endpoint type to use for the endpoints in the
-Keystone service catalog. If Horizon is running external to the OpenStack
-environment you may wish to use ``"publicURL"`` instead.
-
-``API_RESULT_LIMIT``
---------------------
-
-Default: ``1000``
-
-The maximum number of objects (e.g. Swift objects or Glance images) to display
-on a single page before providing a paging element (a "more" link) to paginate
-results.
-
-``API_RESULT_PAGE_SIZE``
-------------------------
-
-Default: ``20``
-
-Similar to ``API_RESULT_LIMIT``. This setting currently only controls the
-Glance image list page size. It will be removed in a future version.
-
-Django Settings (Partial)
-=========================
-
-.. warning::
-
- This is not meant to be anywhere near a complete list of settings for
- Django. You should always consult the upstream documentation, especially
- with regards to deployment considerations and security best-practices.
-
-There are a few key settings you should be aware of for development and the
-most basic of deployments. Further recommendations can be found in the
-Deploying Horizon section of this documentation.
-
-``DEBUG`` and ``TEMPLATE_DEBUG``
---------------------------------
-
-Default: ``True``
-
-Controls whether unhandled exceptions should generate a generic 500 response
-or present the user with a pretty-formatted debug information page.
-
-This setting should **always** be set to ``False`` for production deployments
-as the debug page can display sensitive information to users and attackers
-alike.
-
-``SECRET_KEY``
---------------
-
-This should absolutely be set to a unique (and secret) value for your
-deployment. Unless you are running a load-balancer with multiple Horizon
-installations behind it, each Horizon instance should have a unique secret key.
-
-The ``local_settings.py.example`` file includes a quick-and-easy way to
-generate a secret key for a single installation.
-
-``SECURE_PROXY_SSL_HEADER``, ``CSRF_COOKIE_SECURE`` and ``SESSION_COOKIE_SECURE``
----------------------------------------------------------------------------------
-
-These three settings should be configured if you are deploying Horizon with
-SSL. The values indicated in the default ``local_settings.py.example`` file
-are generally safe to use.
diff --git a/doc/source/topics/tables.rst b/doc/source/topics/tables.rst
deleted file mode 100644
index b59dffb2..00000000
--- a/doc/source/topics/tables.rst
+++ /dev/null
@@ -1,129 +0,0 @@
-======================
-DataTables Topic Guide
-======================
-
-Horizon provides the :mod:`horizon.tables` module to provide
-a convenient, reusable API for building data-driven displays and interfaces.
-The core components of this API fall into three categories: ``DataTables``,
-``Actions``, and ``Class-based Views``.
-
- .. seealso::
-
- For a detailed API information check out the :doc:`DataTables Reference
- Guide </ref/tables>`.
-
-Tables
-======
-
-The majority of interface in a dashboard-style interface ends up being
-tabular displays of the various resources the dashboard interacts with.
-The :class:`~horizon.tables.DataTable` class exists so you don't have to
-reinvent the wheel each time.
-
-Creating your own tables
-------------------------
-
-Creating a table is fairly simple:
-
- #. Create a subclass of :class:`~horizon.tables.DataTable`.
- #. Define columns on it using :class:`~horizon.tables.Column`.
- #. Create an inner ``Meta`` class to contain the special options for
- this table.
- #. Define any actions for the table, and add them to
- :attr:`~horizon.tables.DataTableOptions.table_actions` or
- :attr:`~horizon.tables.DataTableOptions.row_actions`.
-
-Examples of this can be found in any of the ``tables.py`` modules included
-in the reference modules under ``horizon.dashboards``.
-
-Connecting a table to a view
-----------------------------
-
-Once you've got your table set up the way you like it, the next step is to
-wire it up to a view. To make this as easy as possible Horizon provides the
-:class:`~horizon.tables.DataTableView` class-based view which can be subclassed
-to display your table with just a couple lines of code. At it's simplest it
-looks like this::
-
- from horizon import tables
- from .tables import MyTable
-
-
- class MyTableView(tables.DataTableView):
- table_class = MyTable
- template_name = "my_app/my_table_view.html"
-
- def get_data(self):
- return my_api.objects.list()
-
-In the template you would just need to include the following to render the
-table::
-
- {{ table.render }}
-
-That's it! Easy, right?
-
-Actions
-=======
-
-Actions comprise any manipulations that might happen on the data in the table
-or the table itself. For example, this may be the standard object CRUD, linking
-to related views based on the object's id, filtering the data in the table,
-or fetching updated data when appropriate.
-
-When actions get run
---------------------
-
-There are two points in the request-response cycle in which actions can
-take place; prior to data being loaded into the table, and after the data
-is loaded. When you're using one of the pre-built class-based views for
-working with your tables the pseudo-workflow looks like this:
-
- #. The request enters view.
- #. The table class is instantiated without data.
- #. Any "preemptive" actions are checked to see if they should run.
- #. Data is fetched and loaded into the table.
- #. All other actions are checked to see if they should run.
- #. If none of the actions have caused an early exit from the view,
- the standard response from the view is returned (usually the
- rendered table).
-
-The benefit of the multi-step table instantiation is that you can use
-preemptive actions which don't need access to the entire collection of data
-to save yourself on processing overhead, API calls, etc.
-
-Basic actions
--------------
-
-At their simplest, there are three types of actions: actions which act on the
-data in the table, actions which link to related resources, and actions that
-alter which data is displayed. These correspond to
-:class:`~horizon.tables.Action`, :class:`~horizon.tables.LinkAction`, and
-:class:`~horizon.tables.FilterAction`.
-
-Writing your own actions generally starts with subclassing one of those
-action classes and customizing the designated attributes and methods.
-
-Shortcut actions
-----------------
-
-There are several common tasks for which Horizon provides pre-built shortcut
-classes. These include :class:`~horizon.tables.BatchAction`, and
-:class:`~horizon.tables.DeleteAction`. Each of these abstracts away nearly
-all of the boilerplate associated with writing these types of actions and
-provides consistent error handling, logging, and user-facing interaction.
-
-It is worth noting that ``BatchAction`` and ``DeleteAction`` are extensions
-of the standard ``Action`` class.
-
-Preemptive actions
-------------------
-
-Action classes which have their :attr:`~horizon.tables.Action.preempt`
-attribute set to ``True`` will be evaluated before any data is loaded into
-the table. As such, you must be careful not to rely on any table methods that
-require data, such as :meth:`~horizon.tables.DataTable.get_object_display` or
-:meth:`~horizon.tables.DataTable.get_object_by_id`. The advantage of preemptive
-actions is that you can avoid having to do all the processing, API calls, etc.
-associated with loading data into the table for actions which don't require
-access to that information.
diff --git a/doc/source/topics/testing.rst b/doc/source/topics/testing.rst
deleted file mode 100644
index e8afb4d3..00000000
--- a/doc/source/topics/testing.rst
+++ /dev/null
@@ -1,276 +0,0 @@
-===================
-Testing Topic Guide
-===================
-
-Having good tests in place is absolutely critical for ensuring a stable,
-maintainable codebase. Hopefully that doesn't need any more explanation.
-
-However, what defines a "good" test is not always obvious, and there are
-a lot of common pitfalls that can easily shoot your test suite in the
-foot.
-
-If you already know everything about testing but are fed up with trying to
-debug why a specific test failed, you can skip the intro and jump
-stright to :ref:`debugging_unit_tests`.
-
-An overview of testing
-======================
-
-There are three main types of tests, each with their associated pros and cons:
-
-Unit tests
-----------
-
-These are isolated, stand-alone tests with no external dependencies. They are
-written from the a perspective of "knowing the code", and test the assumptions
-of the codebase and the developer.
-
-Pros:
-
-* Generally lightweight and fast.
-* Can be run anywhere, anytime since they have no external dependencies.
-
-Cons:
-
-* Easy to be lax in writing them, or lazy in constructing them.
-* Can't test interactions with live external services.
-
-Functional tests
-----------------
-
-These are generally also isolated tests, though sometimes they may interact
-with other services running locally. The key difference between functional
-tests and unit tests, however, is that functional tests are written from the
-perspective of the user (who knows nothing about the code) and only knows
-what they put in and what they get back. Essentially this is a higher-level
-testing of "does the result match the spec?".
-
-Pros:
-
-* Ensures that your code *always* meets the stated functional requirements.
-* Verifies things from an "end user" perspective, which helps to ensure
- a high-quality experience.
-* Designing your code with a functional testing perspective in mind helps
- keep a higher-level viewpoint in mind.
-
-Cons:
-
-* Requires an additional layer of thinking to define functional requirements
- in terms of inputs and outputs.
-* Often requires writing a separate set of tests and/or using a different
- testing framework from your unit tests.
-* Don't offer any insight into the quality or status of the underlying code,
- only verifies that it works or it doesn't.
-
-Integration Tests
------------------
-
-This layer of testing involves testing all of the components that your
-codebase interacts with or relies on in conjunction. This is equivalent to
-"live" testing, but in a repeatable manner.
-
-Pros:
-
-* Catches *many* bugs that unit and functional tests will not.
-* Doesn't rely on assumptions about the inputs and outputs.
-* Will warn you when changes in external components break your code.
-
-Cons:
-
-* Difficult and time-consuming to create a repeatable test environment.
-* Did I mention that setting it up is a pain?
-
-So what should I write?
------------------------
-
-A few simple guidelines:
-
-#. Every bug fix should have a regression test. Period.
-
-#. When writing a new feature, think about writing unit tests to verify
- the behavior step-by-step as you write the feature. Every time you'd
- go to run your code by hand and verify it manually, think "could I
- write a test to do this instead?". That way when the feature is done
- and you're ready to commit it you've already got a whole set of tests
- that are more thorough than anything you'd write after the fact.
-
-#. Write tests that hit every view in your application. Even if they
- don't assert a single thing about the code, it tells you that your
- users aren't getting fatal errors just by interacting with your code.
-
-What makes a good unit test?
-============================
-
-Limiting our focus just to unit tests, there are a number of things you can
-do to make your unit tests as useful, maintainable, and unburdensome as
-possible.
-
-Test data
----------
-
-Use a single, consistent set of test data. Grow it over time, but do everything
-you can not to fragment it. It quickly becomes unmaintainable and perniciously
-out-of-sync with reality.
-
-Make your test data as accurate to reality as possible. Supply *all* the
-attributes of an object, provide objects in all the various states you may want
-to test.
-
-If you do the first suggestion above *first* it makes the second one far less
-painful. Write once, use everywhere.
-
-To make your life even easier, if your codebase doesn't have a built-in
-ORM-like function to manage your test data you can consider buidling (or
-borrowing) one yourself. Being able to do simple retrieval queries on your
-test data is incredibly valuable.
-
-Mocking
--------
-
-Mocking is the practice of providing stand-ins for objects or pieces of code
-you don't need to test. While convenient, they should be used with *extreme*
-caution.
-
-Why? Because overuse of mocks can rapidly land you in a situation where you're
-not testing any real code. All you've done is verified that your mocking
-framework returns what you tell it to. This problem can be very tricky to
-recognize, since you may be mocking things in ``setUp`` methods, other modules,
-etc.
-
-A good rule of thumb is to mock as close to the source as possible. If you have
-a function call that calls an external API in a view , mock out the external
-API, not the whole function. If you mock the whole function you've suddenly
-lost test coverage for an entire chunk of code *inside* your codebase. Cut the
-ties cleanly right where your system ends and the external world begins.
-
-Similarly, don't mock return values when you could construct a real return
-value of the correct type with the correct attributes. You're just adding
-another point of potential failure by exercising your mocking framework instead
-of real code. Following the suggestions for testing above will make this a lot
-less burdensome.
-
-Assertions and verification
----------------------------
-
-Think long and hard about what you really want to verify in your unit test. In
-particular, think about what custom logic your code executes.
-
-A common pitfall is to take a known test object, pass it through your code,
-and then verify the properties of that object on the output. This is all well
-and good, except if you're verifying properties that were untouched by your
-code. What you want to check are the pieces that were *changed*, *added*, or
-*removed*. Don't check the object's id attribute unless you have reason to
-suspect it's not the object you started with. But if you added a new attribute
-to it, be damn sure you verify that came out right.
-
-It's also very common to avoid testing things you really care about because
-it's more difficult. Verifying that the proper messages were displayed to the
-user after an action, testing for form errors, making sure exception handling
-is tested... these types of things aren't always easy, but they're extremely
-necessary.
-
-To that end, Horizon includes several custom assertions to make these tasks
-easier. :meth:`~horizon.test.helpers.TestCase.assertNoFormErrors`,
-:meth:`~horizon.test.helpers.TestCase.assertMessageCount`, and
-:meth:`~horizon.test.helpers.TestCase.asertNoMessages` all exist for exactly
-these purposes. Moreover, they provide useful output when things go wrong so
-you're not left scratching your head wondering why your view test didn't
-redirect as expected when you posted a form.
-
-.. _debugging_unit_tests:
-
-Debugging Unit Tests
-====================
-
-Tips and tricks
----------------
-
-#. Use :meth:`~horizon.test.helpers.TestCase.assertNoFormErrors` immediately
- after your ``client.post`` call for tests that handle form views. This will
- immediately fail if your form POST failed due to a validation error and
- tell you what the error was.
-
-#. Use :meth:`~horizon.test.helpers.TestCase.assertMessageCount` and
- :meth:`~horizon.test.helpers.TestCase.asertNoMessages` when a piece of code
- is failing inexplicably. Since the core error handlers attach user-facing
- error messages (and since the core logging is silenced during test runs)
- these methods give you the dual benefit of verifying the output you expect
- while clearly showing you the problematic error message if they fail.
-
-#. Use Python's ``pdb`` module liberally. Many people don't realize it works
- just as well in a test case as it does in a live view. Simply inserting
- ``import pdb; pdb.set_trace()`` anywhere in your codebase will drop the
- interpreter into an interactive shell so you can explore your test
- environment and see which of your assumptions about the code isn't,
- in fact, flawlessly correct.
-
-Common pitfalls
----------------
-
-There are a number of typical (and non-obvious) ways to break the unit tests.
-Some common things to look for:
-
-#. Make sure you stub out the method exactly as it's called in the code
- being tested. For example, if your real code calls
- ``api.keystone.tenant_get``, stubbing out ``api.tenant_get`` (available
- for legacy reasons) will fail.
-
-#. When defining the expected input to a stubbed call, make sure the
- arguments are *identical*, this includes ``str`` vs. ``int`` differences.
-
-#. Make sure your test data are completely in line with the expected inputs.
- Again, ``str`` vs. ``int`` or missing properties on test objects will
- kill your tests.
-
-#. Make sure there's nothing amiss in your templates (particularly the
- ``{% url %}`` tag and its arguments). This often comes up when refactoring
- views or renaming context variables. It can easily result in errors that
- you might not stumble across while clicking around the development server.
-
-#. Make sure you're not redirecting to views that no longer exist, e.g.
- the ``index`` view for a panel that got combined (such as instances &
- volumes).
-
-#. Make sure your mock calls are in order before calling ``mox.ReplayAll``.
- The order matters.
-
-#. Make sure you repeat any stubbed out method calls that happen more than
- once. They don't automatically repeat, you have to explicitly define them.
- While this is a nuisance, it makes you acutely aware of how many API
- calls are involved in a particular function.
-
-Understanding the output from ``mox``
--------------------------------------
-
-Horizon uses ``mox`` as its mocking framework of choice, and while it
-offers many nice features, its output when a test fails can be quite
-mysterious.
-
-Unexpected Method Call
-~~~~~~~~~~~~~~~~~~~~~~
-
-This occurs when you stubbed out a piece of code, and it was subsequently
-called in a way that you didn't specify it would be. There are two reasons
-this tends to come up:
-
-#. You defined the expected call, but a subtle difference crept in. This
- may be a string versus integer difference, a string versus unicode
- difference, a slightly off date/time, or passing a name instead of an id.
-
-#. The method is actually being called *multiple times*. Since mox uses
- a call stack internally, it simply pops off the expected method calls to
- verify them. That means once a call is used once, it's gone. An easy way
- to see if this is the case is simply to copy and paste your method call a
- second time to see if the error changes. If it does, that means your method
- is being called more times than you think it is.
-
-Expected Method Never Called
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This one is the opposite of the unexpected method call. This one means you
-tol mox to expect a call and it didn't happen. This is almost always the
-result of an error in the conditions of the test. Using the
-:meth:`~horizon.test.helpers.TestCase.assertNoFormErrors` and
-:meth:`~horizon.test.helpers.TestCase.assertMessageCount` will make it readily
-apparent what the problem is in the majority of cases. If not, then use ``pdb``
-and start interrupting the code flow to see where things are getting off track.
diff --git a/doc/source/topics/tutorial.rst b/doc/source/topics/tutorial.rst
deleted file mode 100644
index 49083fca..00000000
--- a/doc/source/topics/tutorial.rst
+++ /dev/null
@@ -1,556 +0,0 @@
-===================
-Building on Horizon
-===================
-
-This tutorial covers how to use the various components in Horizon to build
-an example dashboard and panel with a data table and tabs.
-
-As an example, we'll build on the Nova instances API to create a new and novel
-"visualizations" dashboard with a "flocking" panel that presents the instance
-data in a different manner.
-
-You can find a reference implementation of the code being described here
-on github at https://github.com/gabrielhurley/horizon_demo.
-
-.. note::
-
- There are a variety of other resources which may be helpful to read first,
- since this is a more advanced tutorial. For example, you may want to start
- with the :doc:`Horizon quickstart guide </quickstart>` or the
- `Django tutorial`_.
-
- .. _Django tutorial: https://docs.djangoproject.com/en/1.4/intro/tutorial01/
-
-
-Creating a dashboard
-====================
-
-.. note::
-
- It is perfectly valid to create a panel without a dashboard, and
- incorporate it into an existing dashboard. See the section
- :ref:`overrides <overrides>` later in this document.
-
-The quick version
------------------
-
-Horizon provides a custom management command to create a typical base
-dashboard structure for you. The following command generates most of the
-boilerplate code explained below::
-
- ./run_tests.sh -m startdash visualizations
-
-It's still recommended that you read the rest of this section to understand
-what that command creates and why.
-
-Structure
----------
-
-The recommended structure for a dashboard (or panel) follows suit with the
-typical Django application layout. We'll name our dashboard "visualizations"::
-
- visualizations
- |--__init__.py
- |--dashboard.py
- |--templates/
- |--static/
-
-The ``dashboard.py`` module will contain our dashboard class for use by
-Horizon; the ``templates`` and ``static`` directories give us homes for our
-Django template files and static media respectively.
-
-Within the ``static`` and ``templates`` directories it's generally good to
-namespace your files like so::
-
- templates/
- |--visualizations/
- static/
- |--visualizations/
- |--css/
- |--js/
- |--img/
-
-With those files and directories in place, we can move on to writing our
-dashboard class.
-
-
-Defining a dashboard
---------------------
-
-A dashboard class can be incredibly simple (about 3 lines at minimum),
-defining nothing more than a name and a slug::
-
- import horizon
-
- class VizDash(horizon.Dashboard):
- name = _("Visualizations")
- slug = "visualizations"
-
-In practice, a dashboard class will usually contain more information, such as a
-list of panels, which panel is the default, and any permissions required to
-access this dashboard::
-
- class VizDash(horizon.Dashboard):
- name = _("Visualizations")
- slug = "visualizations"
- panels = ('flocking',)
- default_panel = 'flocking'
- permissions = ('openstack.roles.admin',)
-
-Building from that previous example we may also want to define a grouping of
-panels which share a common theme and have a sub-heading in the navigation::
-
- class InstanceVisualizations(horizon.PanelGroup):
- slug = "instance_visualizations"
- name = _("Instance Visualizations")
- panels = ('flocking',)
-
-
- class VizDash(horizon.Dashboard):
- name = _("Visualizations")
- slug = "visualizations"
- panels = (InstanceVisualizations,)
- default_panel = 'flocking'
- permissions = ('openstack.roles.admin',)
-
-The ``PanelGroup`` can be added to the dashboard class' ``panels`` list
-just like the slug of the panel can.
-
-Once our dashboard class is complete, all we need to do is register it::
-
- horizon.register(VizDash)
-
-The typical place for that would be the bottom of the ``dashboard.py`` file,
-but it could also go elsewhere, such as in an override file (see below).
-
-
-Creating a panel
-================
-
-Now that we have our dashboard written, we can also create our panel. We'll
-call it "flocking".
-
-.. note::
-
- You don't need to write a custom dashboard to add a panel. The structure
- here is for the sake of completeness in the tutorial.
-
-The quick version
------------------
-
-Horizon provides a custom management command to create a typical base
-panel structure for you. The following command generates most of the
-boilerplate code explained below::
-
- ./run_tests.sh -m startpanel flocking --dashboard=visualizations --target=auto
-
-The ``dashboard`` argument is required, and tells the command which dashboard
-this panel will be registered with. The ``target`` argument is optional, and
-respects ``auto`` as a special value which means that the files for the panel
-should be created inside the dashboard module as opposed to the current
-directory (the default).
-
-It's still recommended that you read the rest of this section to understand
-what that command creates and why.
-
-Structure
----------
-
-A panel is a relatively flat structure with the exception that templates
-for a panel in a dashboard live in the dashboard's ``templates`` directory
-rather than in the panel's ``templates`` directory. Continuing our
-vizulaization/flocking example, let's see what the looks like::
-
- # stand-alone panel structure
- flocking/
- |--__init__.py
- |--panel.py
- |--urls.py
- |--views.py
- |--templates/
- |--flocking/
- |--index.html
-
- # panel-in-a-dashboard structure
- visualizations/
- |--__init__.py
- |--dashboard.py
- |--flocking/
- |--__init__.py
- |--panel.py
- |--urls.py
- |--views.py
- |--templates/
- |--visualizations/
- |--flocking/
- |--index.html
-
-That follows standard Django namespacing conventions for apps and submodules
-within apps. It also works cleanly with Django's automatic template discovery
-in both cases.
-
-Defining a panel
-----------------
-
-The ``panel.py`` file referenced above has a special meaning. Within a
-dashboard, any module name listed in the ``panels`` attribute on the
-dashboard class will be auto-discovered by looking for ``panel.py`` file
-in a corresponding directory (the details are a bit magical, but have been
-thoroughly vetted in Django's admin codebase).
-
-Inside the ``panel.py`` module we define our ``Panel`` class::
-
- class Flocking(horizon.Panel):
- name = _("Flocking")
- slug = 'flocking'
-
-Simple, right? Once we've defined it, we register it with the dashboard::
-
- from visualizations import dashboard
-
- dashboard.VizDash.register(Flocking)
-
-Easy! There are more options you can set to customize the ``Panel`` class, but
-it makes some intelligent guesses about what the defaults should be.
-
-URLs
-----
-
-One of the intelligent assumptions the ``Panel`` class makes is that it can
-find a ``urls.py`` file in your panel directory which will define a view named
-``index`` that handles the default view for that panel. This is what your
-``urls.py`` file might look like::
-
- from django.conf.urls.defaults import patterns, url
- from .views import IndexView
-
- urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index')
- )
-
-There's nothing there that isn't 100% standard Django code. This example
-(and Horizon in general) uses the class-based views introduced in Django 1.3
-to make code more reusable. Hence the view class is imported in the example
-above, and the ``as_view()`` method is called in the URL pattern.
-
-This, of course, presumes you have a view class, and takes us into the meat
-of writing a ``Panel``.
-
-
-Tables, Tabs, and Views
------------------------
-
-Now we get to the really exciting parts; everything before this was structural.
-
-Starting with the high-level view, our end goal is to create a view (our
-``IndexView`` class referenced above) which uses Horizon's ``DataTable``
-class to display data and Horizon's ``TabGroup`` class to give us a
-user-friendly tabbed interface in the browser.
-
-We'll start with the table, combine that with the tabs, and then build our
-view from the pieces.
-
-Defining a table
-~~~~~~~~~~~~~~~~
-
-Horizon provides a :class:`~horizon.tables.DataTable` class which simplifies
-the vast majority of displaying data to an end-user. We're just going to skim
-the surface here, but it has a tremendous number of capabilities.
-
-In this case, we're going to be presenting data about tables, so let's start
-defining our table (and a ``tables.py`` module::
-
- from horizon import tables
-
- class FlockingInstancesTable(tables.DataTable):
- host = tables.Column("OS-EXT-SRV-ATTR:host", verbose_name=_("Host"))
- tenant = tables.Column('tenant_name', verbose_name=_("Tenant"))
- user = tables.Column('user_name', verbose_name=_("user"))
- vcpus = tables.Column('flavor_vcpus', verbose_name=_("VCPUs"))
- memory = tables.Column('flavor_memory', verbose_name=_("Memory"))
- age = tables.Column('age', verbose_name=_("Age"))
-
- class Meta:
- name = "instances"
- verbose_name = _("Instances")
-
-There are several things going on here... we created a table subclass,
-and defined six columns on it. Each of those columns defines what attribute
-it accesses on the instance object as the first argument, and since we like to
-make everything translatable, we give each column a ``verbose_name`` that's
-marked for translation.
-
-Lastly, we added a ``Meta`` class which defines some properties about our
-table, notably it's (translatable) verbose name, and a semi-unique "slug"-like
-name to identify it.
-
-.. note::
-
- This is a slight simplification from the reality of how the instance
- object is actually structured. In reality, accessing the flavor, tenant,
- and user attributes on it requires an additional step. This code can be
- seen in the example code available on github.
-
-Defining tabs
-~~~~~~~~~~~~~
-
-So we have a table, ready to receive our data. We could go straight to a view
-from here, but we can think bigger. In this case we're also going to use
-Horizon's :class:`~horizon.tabs.TabGroup` class. This gives us a clean,
-no-fuss tabbed interface to display both our visualization and, optionally,
-our data table.
-
-First off, let's make a tab for our visualization::
-
- class VizTab(tabs.Tab):
- name = _("Visualization")
- slug = "viz"
- template_name = "visualizations/flocking/_flocking.html"
-
- def get_context_data(self, request):
- return None
-
-This is about as simple as you can get. Since our visualization will
-ultiimately use AJAX to load it's data we don't need to pass any context
-to the template, and all we need to define is the name and which template
-it should use.
-
-Now, we also need a tab for our data table::
-
- from .tables import FlockingInstancesTable
-
- class DataTab(tabs.TableTab):
- name = _("Data")
- slug = "data"
- table_classes = (FlockingInstancesTable,)
- template_name = "horizon/common/_detail_table.html"
- preload = False
-
- def get_instances_data(self):
- try:
- instances = utils.get_instances_data(self.tab_group.request)
- except:
- instances = []
- exceptions.handle(self.tab_group.request,
- _('Unable to retrieve instance list.'))
- return instances
-
-This tab gets a little more complicated. Foremost, it's a special type of
-tab--one that handles data tables (and all their associated features)--and
-it also uses the ``preload`` attribute to specify that this tab shouldn't
-be loaded by default. It will instead be loaded via AJAX when someone clicks
-on it, saving us on API calls in the vast majority of cases.
-
-Lastly, this code introduces the concept of error handling in Horizon.
-The :func:`horizon.exceptions.handle` function is a centralized error
-handling mechanism that takes all the guess-work and inconsistency out of
-dealing with exceptions from the API. Use it everywhere.
-
-Tying it together in a view
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-There are lots of pre-built class-based views in Horizon. We try to provide
-starting points for all the common combinations of components.
-
-In this case we want a starting view type that works with both tabs and
-tables... that'd be the :class:`~horizon.tabs.TabbedTableView` class. It takes
-the best of the dynamic delayed-loading capabilities tab groups provide and
-mixes in the actions and AJAX-updating that tables are capable of with almost
-no work on the user's end. Let's see what the code would look like::
-
- from .tables import FlockingInstancesTable
- from .tabs import FlockingTabs
-
- class IndexView(tabs.TabbedTableView):
- tab_group_class = FlockingTabs
- table_class = FlockingInstancesTable
- template_name = 'visualizations/flocking/index.html'
-
-That would get us 100% of the way to what we need if this particular
-demo didn't involve an extra AJAX call to fetch back our visualization
-data via AJAX. Because of that we need to override the class' ``get()``
-method to return the right data for an AJAX call::
-
- from .tables import FlockingInstancesTable
- from .tabs import FlockingTabs
-
- class IndexView(tabs.TabbedTableView):
- tab_group_class = FlockingTabs
- table_class = FlockingInstancesTable
- template_name = 'visualizations/flocking/index.html'
-
- def get(self, request, *args, **kwargs):
- if self.request.is_ajax() and self.request.GET.get("json", False):
- try:
- instances = utils.get_instances_data(self.request)
- except:
- instances = []
- exceptions.handle(request,
- _('Unable to retrieve instance list.'))
- data = json.dumps([i._apiresource._info for i in instances])
- return http.HttpResponse(data)
- else:
- return super(IndexView, self).get(request, *args, **kwargs)
-
-In this instance, we override the ``get()`` method such that if it's an
-AJAX request and has the GET parameter we're looking for, it returns our
-instance data in JSON format; otherwise it simply returns the view function
-as per the usual.
-
-The template
-~~~~~~~~~~~~
-
-We need three templates here: one for the view, and one for each of our two
-tabs. The view template (in this case) can inherit from one of the other
-dashboards::
-
- {% extends 'base.html' %}
- {% load i18n %}
- {% block title %}{% trans "Flocking" %}{% endblock %}
-
- {% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Flocking") %}
- {% endblock page_header %}
-
- {% block main %}
- <div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
- </div>
- {% endblock %}
-
-This gives us a custom page title, a header, and render our tab group provided
-by the view.
-
-For the tabs, the one using the table is handled by a reusable template,
-``"horizon/common/_detail_table.html"``. This is appropriate for any tab that
-only displays a single table.
-
-The second tab is a bit of secret sauce for the visualization, but it's still
-quite simple and can be investigated in the github example.
-
-The takeaway here is that each tab needs a template associated with it.
-
-With all our code in place, the only thing left to do is to integrated it into
-our OpenStack Dashboard site.
-
-Setting up a project
-====================
-
-The vast majority of people will just customize the OpenStack Dashboard
-example project that ships with Horizon. As such, this tutorial will
-start from that and just illustrate the bits that can be customized.
-
-Structure
----------
-
-A site built on Horizon takes the form of a very typical Django project::
-
- site/
- |--__init__.py
- |--manage.py
- |--demo_dashboard/
- |--__init__.py
- |--models.py # required for Django even if unused
- |--settings.py
- |--templates/
- |--static/
-
-The key bits here are that ``demo_dashboard`` is on our python path, and that
-the `settings.py`` file here will contain our customized Horizon config.
-
-The settings file
------------------
-
-There are several key things you will generally want to customiz in your
-site's settings file: specifying custom dashboards and panels, catching your
-client's exception classes, and (possibly) specifying a file for advanced
-overrides.
-
-Specifying dashboards
-~~~~~~~~~~~~~~~~~~~~~
-
-The most basic thing to do is to add your own custom dashboard using the
-``HORIZON_CONFIG`` dictionary in the settings file::
-
- HORIZON_CONFIG = {
- 'dashboards': ('project', 'admin', 'settings',),
- }
-
-Please note, the dashboards also must be added to settings.py::
- INSTALLED_APPS = (
- 'openstack_dashboard',
- ...
- 'horizon',
- 'openstack_dashboard.dashboards.project',
- 'openstack_dashboard.dashboards.admin',
- 'openstack_dashboard.dashboards.settings',
- ...
- )
-
-In this case, we've taken the default Horizon ``'dashboards'`` config and
-added our ``visualizations`` dashboard to it. Note that the name here is the
-name of the dashboard's module on the python path. It will find our
-``dashboard.py`` file inside of it and load both the dashboard and its panels
-automatically from there.
-
-Error handling
-~~~~~~~~~~~~~~
-
-Adding custom error handler for your API client is quite easy. While it's not
-necessary for this example, it would be done by customizing the
-``'exceptions'`` value in the ``HORIZON_CONFIG`` dictionary::
-
- import my_api.exceptions as my_api
-
- 'exceptions': {'recoverable': [my_api.Error,
- my_api.ClientConnectionError],
- 'not_found': [my_api.NotFound],
- 'unauthorized': [my_api.NotAuthorized]},
-
-.. _overrides:
-
-Override file
-~~~~~~~~~~~~~
-
-The override file is the "god-mode" dashboard editor. The hook for this file
-sits right between the automatic discovery mechanisms and the final setup
-routines for the entire site. By specifying an override file you can alter
-any behavior you like in existing code. This tutorial won't go in-depth,
-but let's just say that with great power comes great responsibility.
-
-To specify am override file, you set the ``'customization_module'`` value in
-the ``HORIZON_CONFIG`` dictionary to the dotted python path of your
-override module::
-
- HORIZON_CONFIG = {
- 'customization_module': 'demo_dashboard.overrides'
- }
-
-This file is capable of adding dashboards, adding panels to existing
-dashboards, renaming existing dashboards and panels (or altering other
-attributes on them), removing panels from existing dashboards, and so on.
-
-We could say more, but it only gets more dangerous...
-
-Conclusion
-==========
-
-Sadly, the cake was a lie. The information in this "tutorial" was never
-meant to leave you with a working dashboard. It's close. But there's
-waaaaaay too much javascript involved in the visualization to cover it all
-here, and it'd be irrelevant to Horizon anyway.
-
-If you want to see the finished product, check out the github example
-referenced at the beginning of this tutorial.
-
-Clone the repository and simply run ``./run_tests.sh --runserver``. That'll
-give you a 100% working dashboard that uses every technique in this tutorial.
-
-What you've learned here, however, is the fundamentals of almost everything
-you need to know to start writing interfaces for your own project based on the
-components Horizon provides.
-
-If you have questions, or feedback on how this tutorial could be improved,
-please feel free to pass them along!
diff --git a/horizon/__init__.py b/horizon/__init__.py
deleted file mode 100644
index 7325d29d..00000000
--- a/horizon/__init__.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-""" The Horizon interface.
-
-Contains the core Horizon classes--:class:`~horizon.Dashboard` and
-:class:`horizon.Panel`--the dynamic URLconf for Horizon, and common interface
-methods like :func:`~horizon.register` and :func:`~horizon.unregister`.
-
-"""
-# Because this module is compiled by setup.py before Django may be installed
-# in the environment we try importing Django and issue a warning but move on
-# should that fail.
-Horizon = None
-try:
- from horizon.base import Dashboard
- from horizon.base import Horizon
- from horizon.base import Panel
- from horizon.base import PanelGroup
-except ImportError:
- import warnings
-
- def simple_warn(message, category, filename, lineno, file=None, line=None):
- return '%s: %s' % (category.__name__, message)
-
- msg = ("Could not import Horizon dependencies. "
- "This is normal during installation.\n")
- warnings.formatwarning = simple_warn
- warnings.warn(msg, Warning)
-
-if Horizon:
- register = Horizon.register
- unregister = Horizon.unregister
- get_absolute_url = Horizon.get_absolute_url
- get_user_home = Horizon.get_user_home
- get_dashboard = Horizon.get_dashboard
- get_default_dashboard = Horizon.get_default_dashboard
- get_dashboards = Horizon.get_dashboards
- urls = Horizon._lazy_urls
-
-# silence flake8 about unused imports here:
-assert Dashboard
-assert Panel
-assert PanelGroup
diff --git a/horizon/base.py b/horizon/base.py
deleted file mode 100644
index 32643394..00000000
--- a/horizon/base.py
+++ /dev/null
@@ -1,803 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Contains the core classes and functionality that makes Horizon what it is.
-This module is considered internal, and should not be relied on directly.
-
-Public APIs are made available through the :mod:`horizon` module and
-the classes contained therein.
-"""
-
-import collections
-import copy
-import inspect
-import logging
-import os
-
-from django.conf import settings
-from django.conf.urls.defaults import include
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-from django.core.exceptions import ImproperlyConfigured
-from django.core.urlresolvers import reverse
-from django.utils.datastructures import SortedDict
-from django.utils.functional import SimpleLazyObject
-from django.utils.importlib import import_module
-from django.utils.module_loading import module_has_submodule
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import conf
-from horizon.decorators import _current_component
-from horizon.decorators import require_auth
-from horizon.decorators import require_perms
-from horizon import loaders
-
-
-LOG = logging.getLogger(__name__)
-
-
-def _decorate_urlconf(urlpatterns, decorator, *args, **kwargs):
- for pattern in urlpatterns:
- if getattr(pattern, 'callback', None):
- pattern._callback = decorator(pattern.callback, *args, **kwargs)
- if getattr(pattern, 'url_patterns', []):
- _decorate_urlconf(pattern.url_patterns, decorator, *args, **kwargs)
-
-
-class NotRegistered(Exception):
- pass
-
-
-class HorizonComponent(object):
- def __init__(self):
- super(HorizonComponent, self).__init__()
- if not self.slug:
- raise ImproperlyConfigured('Every %s must have a slug.'
- % self.__class__)
-
- def __unicode__(self):
- name = getattr(self, 'name', u"Unnamed %s" % self.__class__.__name__)
- return unicode(name)
-
- def _get_default_urlpatterns(self):
- package_string = '.'.join(self.__module__.split('.')[:-1])
- if getattr(self, 'urls', None):
- try:
- mod = import_module('.%s' % self.urls, package_string)
- except ImportError:
- mod = import_module(self.urls)
- urlpatterns = mod.urlpatterns
- else:
- # Try importing a urls.py from the dashboard package
- if module_has_submodule(import_module(package_string), 'urls'):
- urls_mod = import_module('.urls', package_string)
- urlpatterns = urls_mod.urlpatterns
- else:
- urlpatterns = patterns('')
- return urlpatterns
-
-
-class Registry(object):
- def __init__(self):
- self._registry = {}
- if not getattr(self, '_registerable_class', None):
- raise ImproperlyConfigured('Subclasses of Registry must set a '
- '"_registerable_class" property.')
-
- def _register(self, cls):
- """Registers the given class.
-
- If the specified class is already registered then it is ignored.
- """
- if not inspect.isclass(cls):
- raise ValueError('Only classes may be registered.')
- elif not issubclass(cls, self._registerable_class):
- raise ValueError('Only %s classes or subclasses may be registered.'
- % self._registerable_class.__name__)
-
- if cls not in self._registry:
- cls._registered_with = self
- self._registry[cls] = cls()
-
- return self._registry[cls]
-
- def _unregister(self, cls):
- """Unregisters the given class.
-
- If the specified class isn't registered, ``NotRegistered`` will
- be raised.
- """
- if not issubclass(cls, self._registerable_class):
- raise ValueError('Only %s classes or subclasses may be '
- 'unregistered.' % self._registerable_class)
-
- if cls not in self._registry.keys():
- raise NotRegistered('%s is not registered' % cls)
-
- del self._registry[cls]
-
- return True
-
- def _registered(self, cls):
- if inspect.isclass(cls) and issubclass(cls, self._registerable_class):
- found = self._registry.get(cls, None)
- if found:
- return found
- else:
- # Allow for fetching by slugs as well.
- for registered in self._registry.values():
- if registered.slug == cls:
- return registered
- class_name = self._registerable_class.__name__
- if hasattr(self, "_registered_with"):
- parent = self._registered_with._registerable_class.__name__
- raise NotRegistered('%(type)s with slug "%(slug)s" is not '
- 'registered with %(parent)s "%(name)s".'
- % {"type": class_name,
- "slug": cls,
- "parent": parent,
- "name": self.slug})
- else:
- slug = getattr(cls, "slug", cls)
- raise NotRegistered('%(type)s with slug "%(slug)s" is not '
- 'registered.' % {"type": class_name,
- "slug": slug})
-
-
-class Panel(HorizonComponent):
- """ A base class for defining Horizon dashboard panels.
-
- All Horizon dashboard panels should extend from this class. It provides
- the appropriate hooks for automatically constructing URLconfs, and
- providing permission-based access control.
-
- .. attribute:: name
-
- The name of the panel. This will be displayed in the
- auto-generated navigation and various other places.
- Default: ``''``.
-
- .. attribute:: slug
-
- A unique "short name" for the panel. The slug is used as
- a component of the URL path for the panel. Default: ``''``.
-
- .. attribute:: permissions
-
- A list of permission names, all of which a user must possess in order
- to access any view associated with this panel. This attribute
- is combined cumulatively with any permissions required on the
- ``Dashboard`` class with which it is registered.
-
- .. attribute:: urls
-
- Path to a URLconf of views for this panel using dotted Python
- notation. If no value is specified, a file called ``urls.py``
- living in the same package as the ``panel.py`` file is used.
- Default: ``None``.
-
- .. attribute:: nav
- .. method:: nav(context)
-
- The ``nav`` attribute can be either boolean value or a callable
- which accepts a ``RequestContext`` object as a single argument
- to control whether or not this panel should appear in
- automatically-generated navigation. Default: ``True``.
-
- .. attribute:: index_url_name
-
- The ``name`` argument for the URL pattern which corresponds to
- the index view for this ``Panel``. This is the view that
- :meth:`.Panel.get_absolute_url` will attempt to reverse.
- """
- name = ''
- slug = ''
- urls = None
- nav = True
- index_url_name = "index"
-
- def __repr__(self):
- return "<Panel: %s>" % self.slug
-
- def get_absolute_url(self):
- """ Returns the default URL for this panel.
-
- The default URL is defined as the URL pattern with ``name="index"`` in
- the URLconf for this panel.
- """
- try:
- return reverse('horizon:%s:%s:%s' % (self._registered_with.slug,
- self.slug,
- self.index_url_name))
- except Exception as exc:
- # Logging here since this will often be called in a template
- # where the exception would be hidden.
- LOG.info("Error reversing absolute URL for %s: %s" % (self, exc))
- raise
-
- @property
- def _decorated_urls(self):
- urlpatterns = self._get_default_urlpatterns()
-
- # Apply access controls to all views in the patterns
- permissions = getattr(self, 'permissions', [])
- _decorate_urlconf(urlpatterns, require_perms, permissions)
- _decorate_urlconf(urlpatterns, _current_component, panel=self)
-
- # Return the three arguments to django.conf.urls.defaults.include
- return urlpatterns, self.slug, self.slug
-
-
-class PanelGroup(object):
- """ A container for a set of :class:`~horizon.Panel` classes.
-
- When iterated, it will yield each of the ``Panel`` instances it
- contains.
-
- .. attribute:: slug
-
- A unique string to identify this panel group. Required.
-
- .. attribute:: name
-
- A user-friendly name which will be used as the group heading in
- places such as the navigation. Default: ``None``.
-
- .. attribute:: panels
-
- A list of panel module names which should be contained within this
- grouping.
- """
- def __init__(self, dashboard, slug=None, name=None, panels=None):
- self.dashboard = dashboard
- self.slug = slug or getattr(self, "slug", "default")
- self.name = name or getattr(self, "name", None)
- # Our panels must be mutable so it can be extended by others.
- self.panels = list(panels or getattr(self, "panels", []))
-
- def __repr__(self):
- return "<%s: %s>" % (self.__class__.__name__, self.slug)
-
- def __unicode__(self):
- return self.name
-
- def __iter__(self):
- panel_instances = []
- for name in self.panels:
- try:
- panel_instances.append(self.dashboard.get_panel(name))
- except NotRegistered as e:
- LOG.debug(e)
- return iter(panel_instances)
-
-
-class Dashboard(Registry, HorizonComponent):
- """ A base class for defining Horizon dashboards.
-
- All Horizon dashboards should extend from this base class. It provides the
- appropriate hooks for automatic discovery of :class:`~horizon.Panel`
- modules, automatically constructing URLconfs, and providing
- permission-based access control.
-
- .. attribute:: name
-
- The name of the dashboard. This will be displayed in the
- auto-generated navigation and various other places.
- Default: ``''``.
-
- .. attribute:: slug
-
- A unique "short name" for the dashboard. The slug is used as
- a component of the URL path for the dashboard. Default: ``''``.
-
- .. attribute:: panels
-
- The ``panels`` attribute can be either a flat list containing the name
- of each panel **module** which should be loaded as part of this
- dashboard, or a list of :class:`~horizon.PanelGroup` classes which
- define groups of panels as in the following example::
-
- class SystemPanels(horizon.PanelGroup):
- slug = "syspanel"
- name = _("System Panel")
- panels = ('overview', 'instances', ...)
-
- class Syspanel(horizon.Dashboard):
- panels = (SystemPanels,)
-
- Automatically generated navigation will use the order of the
- modules in this attribute.
-
- Default: ``[]``.
-
- .. warning::
-
- The values for this attribute should not correspond to the
- :attr:`~.Panel.name` attributes of the ``Panel`` classes.
- They should be the names of the Python modules in which the
- ``panel.py`` files live. This is used for the automatic
- loading and registration of ``Panel`` classes much like
- Django's ``ModelAdmin`` machinery.
-
- Panel modules must be listed in ``panels`` in order to be
- discovered by the automatic registration mechanism.
-
- .. attribute:: default_panel
-
- The name of the panel which should be treated as the default
- panel for the dashboard, i.e. when you visit the root URL
- for this dashboard, that's the panel that is displayed.
- Default: ``None``.
-
- .. attribute:: permissions
-
- A list of permission names, all of which a user must possess in order
- to access any panel registered with this dashboard. This attribute
- is combined cumulatively with any permissions required on individual
- :class:`~horizon.Panel` classes.
-
- .. attribute:: urls
-
- Optional path to a URLconf of additional views for this dashboard
- which are not connected to specific panels. Default: ``None``.
-
- .. attribute:: nav
-
- Optional boolean to control whether or not this dashboard should
- appear in automatically-generated navigation. Default: ``True``.
-
- .. attribute:: supports_tenants
-
- Optional boolean that indicates whether or not this dashboard includes
- support for projects/tenants. If set to ``True`` this dashboard's
- navigation will include a UI element that allows the user to select
- project/tenant. Default: ``False``.
-
- .. attribute:: public
-
- Boolean value to determine whether this dashboard can be viewed
- without being logged in. Defaults to ``False``.
- """
- _registerable_class = Panel
- name = ''
- slug = ''
- urls = None
- panels = []
- default_panel = None
- nav = True
- supports_tenants = False
- public = False
-
- def __repr__(self):
- return "<Dashboard: %s>" % self.slug
-
- def __init__(self, *args, **kwargs):
- super(Dashboard, self).__init__(*args, **kwargs)
- self._panel_groups = None
-
- def get_panel(self, panel):
- """
- Returns the specified :class:`~horizon.Panel` instance registered
- with this dashboard.
- """
- return self._registered(panel)
-
- def get_panels(self):
- """
- Returns the :class:`~horizon.Panel` instances registered with this
- dashboard in order, without any panel groupings.
- """
- all_panels = []
- panel_groups = self.get_panel_groups()
- for panel_group in panel_groups.values():
- all_panels.extend(panel_group)
- return all_panels
-
- def get_panel_group(self, slug):
- return self._panel_groups[slug]
-
- def get_panel_groups(self):
- registered = copy.copy(self._registry)
- panel_groups = []
-
- # Gather our known panels
- if self._panel_groups is not None:
- for panel_group in self._panel_groups.values():
- for panel in panel_group:
- registered.pop(panel.__class__)
- panel_groups.append((panel_group.slug, panel_group))
-
- # Deal with leftovers (such as add-on registrations)
- if len(registered):
- slugs = [panel.slug for panel in registered.values()]
- new_group = PanelGroup(self,
- slug="other",
- name=_("Other"),
- panels=slugs)
- panel_groups.append((new_group.slug, new_group))
- return SortedDict(panel_groups)
-
- def get_absolute_url(self):
- """ Returns the default URL for this dashboard.
-
- The default URL is defined as the URL pattern with ``name="index"``
- in the URLconf for the :class:`~horizon.Panel` specified by
- :attr:`~horizon.Dashboard.default_panel`.
- """
- try:
- return self._registered(self.default_panel).get_absolute_url()
- except:
- # Logging here since this will often be called in a template
- # where the exception would be hidden.
- LOG.exception("Error reversing absolute URL for %s." % self)
- raise
-
- @property
- def _decorated_urls(self):
- urlpatterns = self._get_default_urlpatterns()
-
- default_panel = None
-
- # Add in each panel's views except for the default view.
- for panel in self._registry.values():
- if panel.slug == self.default_panel:
- default_panel = panel
- continue
- urlpatterns += patterns('',
- url(r'^%s/' % panel.slug, include(panel._decorated_urls)))
- # Now the default view, which should come last
- if not default_panel:
- raise NotRegistered('The default panel "%s" is not registered.'
- % self.default_panel)
- urlpatterns += patterns('',
- url(r'', include(default_panel._decorated_urls)))
-
- # Require login if not public.
- if not self.public:
- _decorate_urlconf(urlpatterns, require_auth)
- # Apply access controls to all views in the patterns
- permissions = getattr(self, 'permissions', [])
- _decorate_urlconf(urlpatterns, require_perms, permissions)
- _decorate_urlconf(urlpatterns, _current_component, dashboard=self)
-
- # Return the three arguments to django.conf.urls.defaults.include
- return urlpatterns, self.slug, self.slug
-
- def _autodiscover(self):
- """ Discovers panels to register from the current dashboard module. """
- if getattr(self, "_autodiscover_complete", False):
- return
-
- panels_to_discover = []
- panel_groups = []
- # If we have a flat iterable of panel names, wrap it again so
- # we have a consistent structure for the next step.
- if all([isinstance(i, basestring) for i in self.panels]):
- self.panels = [self.panels]
-
- # Now iterate our panel sets.
- for panel_set in self.panels:
- # Instantiate PanelGroup classes.
- if not isinstance(panel_set, collections.Iterable) and \
- issubclass(panel_set, PanelGroup):
- panel_group = panel_set(self)
- # Check for nested tuples, and convert them to PanelGroups
- elif not isinstance(panel_set, PanelGroup):
- panel_group = PanelGroup(self, panels=panel_set)
-
- # Put our results into their appropriate places
- panels_to_discover.extend(panel_group.panels)
- panel_groups.append((panel_group.slug, panel_group))
-
- self._panel_groups = SortedDict(panel_groups)
-
- # Do the actual discovery
- package = '.'.join(self.__module__.split('.')[:-1])
- mod = import_module(package)
- for panel in panels_to_discover:
- try:
- before_import_registry = copy.copy(self._registry)
- import_module('.%s.panel' % panel, package)
- except:
- self._registry = before_import_registry
- if module_has_submodule(mod, panel):
- raise
- self._autodiscover_complete = True
-
- @classmethod
- def register(cls, panel):
- """ Registers a :class:`~horizon.Panel` with this dashboard. """
- panel_class = Horizon.register_panel(cls, panel)
- # Support template loading from panel template directories.
- panel_mod = import_module(panel.__module__)
- panel_dir = os.path.dirname(panel_mod.__file__)
- template_dir = os.path.join(panel_dir, "templates")
- if os.path.exists(template_dir):
- key = os.path.join(cls.slug, panel.slug)
- loaders.panel_template_dirs[key] = template_dir
- return panel_class
-
- @classmethod
- def unregister(cls, panel):
- """ Unregisters a :class:`~horizon.Panel` from this dashboard. """
- success = Horizon.unregister_panel(cls, panel)
- if success:
- # Remove the panel's template directory.
- key = os.path.join(cls.slug, panel.slug)
- if key in loaders.panel_template_dirs:
- del loaders.panel_template_dirs[key]
- return success
-
-
-class Workflow(object):
- def __init__(*args, **kwargs):
- raise NotImplementedError()
-
-
-try:
- from django.utils.functional import empty
-except ImportError:
- #Django 1.3 fallback
- empty = None
-
-
-class LazyURLPattern(SimpleLazyObject):
- def __iter__(self):
- if self._wrapped is empty:
- self._setup()
- return iter(self._wrapped)
-
- def __reversed__(self):
- if self._wrapped is empty:
- self._setup()
- return reversed(self._wrapped)
-
- def __len__(self):
- if self._wrapped is empty:
- self._setup()
- return len(self._wrapped)
-
- def __getitem__(self, idx):
- if self._wrapped is empty:
- self._setup()
- return self._wrapped[idx]
-
-
-class Site(Registry, HorizonComponent):
- """ The overarching class which encompasses all dashboards and panels. """
-
- # Required for registry
- _registerable_class = Dashboard
-
- name = "Horizon"
- namespace = 'horizon'
- slug = 'horizon'
- urls = 'horizon.site_urls'
-
- def __repr__(self):
- return u"<Site: %s>" % self.slug
-
- @property
- def _conf(self):
- return conf.HORIZON_CONFIG
-
- @property
- def dashboards(self):
- return self._conf['dashboards']
-
- @property
- def default_dashboard(self):
- return self._conf['default_dashboard']
-
- def register(self, dashboard):
- """ Registers a :class:`~horizon.Dashboard` with Horizon."""
- return self._register(dashboard)
-
- def unregister(self, dashboard):
- """ Unregisters a :class:`~horizon.Dashboard` from Horizon. """
- return self._unregister(dashboard)
-
- def registered(self, dashboard):
- return self._registered(dashboard)
-
- def register_panel(self, dashboard, panel):
- dash_instance = self.registered(dashboard)
- return dash_instance._register(panel)
-
- def unregister_panel(self, dashboard, panel):
- dash_instance = self.registered(dashboard)
- if not dash_instance:
- raise NotRegistered("The dashboard %s is not registered."
- % dashboard)
- return dash_instance._unregister(panel)
-
- def get_dashboard(self, dashboard):
- """ Returns the specified :class:`~horizon.Dashboard` instance. """
- return self._registered(dashboard)
-
- def get_dashboards(self):
- """ Returns an ordered tuple of :class:`~horizon.Dashboard` modules.
-
- Orders dashboards according to the ``"dashboards"`` key in
- ``HORIZON_CONFIG`` or else returns all registered dashboards
- in alphabetical order.
-
- Any remaining :class:`~horizon.Dashboard` classes registered with
- Horizon but not listed in ``HORIZON_CONFIG['dashboards']``
- will be appended to the end of the list alphabetically.
- """
- if self.dashboards:
- registered = copy.copy(self._registry)
- dashboards = []
- for item in self.dashboards:
- dashboard = self._registered(item)
- dashboards.append(dashboard)
- registered.pop(dashboard.__class__)
- if len(registered):
- extra = registered.values()
- extra.sort()
- dashboards.extend(extra)
- return dashboards
- else:
- dashboards = self._registry.values()
- dashboards.sort()
- return dashboards
-
- def get_default_dashboard(self):
- """ Returns the default :class:`~horizon.Dashboard` instance.
-
- If ``"default_dashboard"`` is specified in ``HORIZON_CONFIG``
- then that dashboard will be returned. If not, the first dashboard
- returned by :func:`~horizon.get_dashboards` will be returned.
- """
- if self.default_dashboard:
- return self._registered(self.default_dashboard)
- elif len(self._registry):
- return self.get_dashboards()[0]
- else:
- raise NotRegistered("No dashboard modules have been registered.")
-
- def get_user_home(self, user):
- """ Returns the default URL for a particular user.
-
- This method can be used to customize where a user is sent when
- they log in, etc. By default it returns the value of
- :meth:`get_absolute_url`.
-
- An alternative function can be supplied to customize this behavior
- by specifying a either a URL or a function which returns a URL via
- the ``"user_home"`` key in ``HORIZON_CONFIG``. Each of these
- would be valid::
-
- {"user_home": "/home",} # A URL
- {"user_home": "my_module.get_user_home",} # Path to a function
- {"user_home": lambda user: "/" + user.name,} # A function
- {"user_home": None,} # Will always return the default dashboard
-
- This can be useful if the default dashboard may not be accessible
- to all users. When user_home is missing from HORIZON_CONFIG,
- it will default to the settings.LOGIN_REDIRECT_URL value.
- """
- user_home = self._conf['user_home']
- if user_home:
- if callable(user_home):
- return user_home(user)
- elif isinstance(user_home, basestring):
- # Assume we've got a URL if there's a slash in it
- if user_home.find("/") != -1:
- return user_home
- else:
- mod, func = user_home.rsplit(".", 1)
- return getattr(import_module(mod), func)(user)
- # If it's not callable and not a string, it's wrong.
- raise ValueError('The user_home setting must be either a string '
- 'or a callable object (e.g. a function).')
- else:
- return self.get_absolute_url()
-
- def get_absolute_url(self):
- """ Returns the default URL for Horizon's URLconf.
-
- The default URL is determined by calling
- :meth:`~horizon.Dashboard.get_absolute_url`
- on the :class:`~horizon.Dashboard` instance returned by
- :meth:`~horizon.get_default_dashboard`.
- """
- return self.get_default_dashboard().get_absolute_url()
-
- @property
- def _lazy_urls(self):
- """ Lazy loading for URL patterns.
-
- This method avoids problems associated with attempting to evaluate
- the the URLconf before the settings module has been loaded.
- """
- def url_patterns():
- return self._urls()[0]
-
- return LazyURLPattern(url_patterns), self.namespace, self.slug
-
- def _urls(self):
- """ Constructs the URLconf for Horizon from registered Dashboards. """
- urlpatterns = self._get_default_urlpatterns()
- self._autodiscover()
-
- # Discover each dashboard's panels.
- for dash in self._registry.values():
- dash._autodiscover()
-
- # Allow for override modules
- if self._conf.get("customization_module", None):
- customization_module = self._conf["customization_module"]
- bits = customization_module.split('.')
- mod_name = bits.pop()
- package = '.'.join(bits)
- mod = import_module(package)
- try:
- before_import_registry = copy.copy(self._registry)
- import_module('%s.%s' % (package, mod_name))
- except:
- self._registry = before_import_registry
- if module_has_submodule(mod, mod_name):
- raise
-
- # Compile the dynamic urlconf.
- for dash in self._registry.values():
- urlpatterns += patterns('',
- url(r'^%s/' % dash.slug, include(dash._decorated_urls)))
-
- # Return the three arguments to django.conf.urls.defaults.include
- return urlpatterns, self.namespace, self.slug
-
- def _autodiscover(self):
- """ Discovers modules to register from ``settings.INSTALLED_APPS``.
-
- This makes sure that the appropriate modules get imported to register
- themselves with Horizon.
- """
- if not getattr(self, '_registerable_class', None):
- raise ImproperlyConfigured('You must set a '
- '"_registerable_class" property '
- 'in order to use autodiscovery.')
- # Discover both dashboards and panels, in that order
- for mod_name in ('dashboard', 'panel'):
- for app in settings.INSTALLED_APPS:
- mod = import_module(app)
- try:
- before_import_registry = copy.copy(self._registry)
- import_module('%s.%s' % (app, mod_name))
- except:
- self._registry = before_import_registry
- if module_has_submodule(mod, mod_name):
- raise
-
-
-class HorizonSite(Site):
- """
- A singleton implementation of Site such that all dealings with horizon
- get the same instance no matter what. There can be only one.
- """
- _instance = None
-
- def __new__(cls, *args, **kwargs):
- if not cls._instance:
- cls._instance = super(Site, cls).__new__(cls, *args, **kwargs)
- return cls._instance
-
-
-# The one true Horizon
-Horizon = HorizonSite()
diff --git a/horizon/browsers/__init__.py b/horizon/browsers/__init__.py
deleted file mode 100644
index e6a2570d..00000000
--- a/horizon/browsers/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from horizon.browsers.base import ResourceBrowser
-from horizon.browsers.views import ResourceBrowserView
-
-assert ResourceBrowser
-assert ResourceBrowserView
diff --git a/horizon/browsers/base.py b/horizon/browsers/base.py
deleted file mode 100644
index 11bcd446..00000000
--- a/horizon/browsers/base.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django import template
-from django.utils.translation import ugettext_lazy as _
-
-from horizon.browsers.breadcrumb import Breadcrumb
-from horizon.tables import DataTable
-from horizon.utils import html
-
-
-class ResourceBrowser(html.HTMLElement):
- """A class which defines a browser for displaying data.
-
- .. attribute:: name
-
- A short name or slug for the browser.
-
- .. attribute:: verbose_name
-
- A more verbose name for the browser meant for display purposes.
-
- .. attribute:: navigation_table_class
-
- This table displays data on the left side of the browser.
- Set the ``navigation_table_class`` attribute with
- the desired :class:`~horizon.tables.DataTable` class.
- This table class must set browser_table attribute in Meta to
- ``"navigation"``.
-
- .. attribute:: content_table_class
-
- This table displays data on the right side of the browser.
- Set the ``content_table_class`` attribute with
- the desired :class:`~horizon.tables.DataTable` class.
- This table class must set browser_table attribute in Meta to
- ``"content"``.
-
- .. attribute:: navigation_kwarg_name
-
- This attribute represents the key of the navigatable items in the
- kwargs property of this browser's view.
- Defaults to ``"navigation_kwarg"``.
-
- .. attribute:: content_kwarg_name
-
- This attribute represents the key of the content items in the
- kwargs property of this browser's view.
- Defaults to ``"content_kwarg"``.
-
- .. attribute:: template
-
- String containing the template which should be used to render
- the browser. Defaults to ``"horizon/common/_resource_browser.html"``.
-
- .. attribute:: context_var_name
-
- The name of the context variable which will contain the browser when
- it is rendered. Defaults to ``"browser"``.
-
- .. attribute:: has_breadcrumb
-
- Indicates if the content table of the browser would have breadcrumb.
- Defaults to false.
-
- .. attribute:: breadcrumb_template
-
- This is a template used to render the breadcrumb.
- Defaults to ``"horizon/common/_breadcrumb.html"``.
- """
- name = None
- verbose_name = None
- navigation_table_class = None
- content_table_class = None
- navigation_kwarg_name = "navigation_kwarg"
- content_kwarg_name = "content_kwarg"
- navigable_item_name = _("Navigation Item")
- template = "horizon/common/_resource_browser.html"
- context_var_name = "browser"
- has_breadcrumb = False
- breadcrumb_template = "horizon/common/_breadcrumb.html"
- breadcrumb_url = None
-
- def __init__(self, request, tables_dict=None, attrs=None, **kwargs):
- super(ResourceBrowser, self).__init__()
- self.name = self.name or self.__class__.__name__
- self.verbose_name = self.verbose_name or self.name.title()
- self.request = request
- self.kwargs = kwargs
- self.has_breadcrumb = getattr(self, "has_breadcrumb")
- if self.has_breadcrumb:
- self.breadcrumb_template = getattr(self, "breadcrumb_template")
- self.breadcrumb_url = getattr(self, "breadcrumb_url")
- if not self.breadcrumb_url:
- raise ValueError("You must specify a breadcrumb_url "
- "if the has_breadcrumb is set to True.")
- self.attrs.update(attrs or {})
- self.check_table_class(self.content_table_class, "content_table_class")
- self.check_table_class(self.navigation_table_class,
- "navigation_table_class")
- if tables_dict:
- self.set_tables(tables_dict)
-
- def check_table_class(self, cls, attr_name):
- if not cls or not issubclass(cls, DataTable):
- raise ValueError("You must specify a DataTable subclass for "
- "the %s attribute on %s."
- % (attr_name, self.__class__.__name__))
-
- def set_tables(self, tables):
- """
- Sets the table instances on the browser from a dictionary mapping table
- names to table instances (as constructed by MultiTableView).
- """
- self.navigation_table = tables[self.navigation_table_class._meta.name]
- self.content_table = tables[self.content_table_class._meta.name]
- navigation_item = self.kwargs.get(self.navigation_kwarg_name)
- content_path = self.kwargs.get(self.content_kwarg_name)
- # Tells the navigation table what is selected.
- self.navigation_table.current_item_id = navigation_item
- if self.has_breadcrumb:
- self.prepare_breadcrumb(tables, navigation_item, content_path)
-
- def prepare_breadcrumb(self, tables, navigation_item, content_path):
- if self.has_breadcrumb and navigation_item and content_path:
- for table in tables.values():
- table.breadcrumb = Breadcrumb(self.request,
- self.breadcrumb_template,
- navigation_item,
- content_path,
- self.breadcrumb_url)
-
- def render(self):
- browser_template = template.loader.get_template(self.template)
- extra_context = {self.context_var_name: self}
- context = template.RequestContext(self.request, extra_context)
- return browser_template.render(context)
diff --git a/horizon/browsers/breadcrumb.py b/horizon/browsers/breadcrumb.py
deleted file mode 100644
index ba1ca748..00000000
--- a/horizon/browsers/breadcrumb.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django import template
-
-from horizon.utils import html
-
-
-class Breadcrumb(html.HTMLElement):
- def __init__(self, request, template, root,
- subfolder_path, url, attr=None):
- super(Breadcrumb, self).__init__()
- self.template = template
- self.request = request
- self.root = root
- self.subfolder_path = subfolder_path
- self.url = url
- self._subfolders = []
-
- def get_subfolders(self):
- if self.subfolder_path and not self._subfolders:
- (parent, slash, folder) = self.subfolder_path.strip('/') \
- .rpartition('/')
- while folder:
- path = "%s%s%s/" % (parent, slash, folder)
- self._subfolders.insert(0, (folder, path))
- (parent, slash, folder) = parent.rpartition('/')
- return self._subfolders
-
- def render(self):
- """ Renders the table using the template from the table options. """
- breadcrumb_template = template.loader.get_template(self.template)
- extra_context = {"breadcrumb": self}
- context = template.RequestContext(self.request, extra_context)
- return breadcrumb_template.render(context)
diff --git a/horizon/browsers/views.py b/horizon/browsers/views.py
deleted file mode 100644
index c2e8b437..00000000
--- a/horizon/browsers/views.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon.tables import MultiTableView
-
-
-class ResourceBrowserView(MultiTableView):
- browser_class = None
-
- def __init__(self, *args, **kwargs):
- if not self.browser_class:
- raise ValueError("You must specify a ResourceBrowser subclass "
- "for the browser_class attribute on %s."
- % self.__class__.__name__)
- self.table_classes = (self.browser_class.navigation_table_class,
- self.browser_class.content_table_class)
- self.navigation_selection = False
- super(ResourceBrowserView, self).__init__(*args, **kwargs)
-
- def get_browser(self):
- if not hasattr(self, "browser"):
- self.browser = self.browser_class(self.request, **self.kwargs)
- self.browser.set_tables(self.get_tables())
- if not self.navigation_selection:
- ct = self.browser.content_table
- item = self.browser.navigable_item_name.lower()
- ct._no_data_message = _("Select a %s to browse.") % item
- return self.browser
-
- def get_context_data(self, **kwargs):
- context = super(ResourceBrowserView, self).get_context_data(**kwargs)
- browser = self.get_browser()
- context["%s_browser" % browser.name] = browser
- return context
diff --git a/horizon/conf/__init__.py b/horizon/conf/__init__.py
deleted file mode 100644
index 4370028d..00000000
--- a/horizon/conf/__init__.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import copy
-
-from django.utils.functional import empty
-from django.utils.functional import LazyObject
-
-
-class LazySettings(LazyObject):
- def _setup(self, name=None):
- from django.conf import settings
- from horizon.conf.default import HORIZON_CONFIG as DEFAULT_CONFIG
- HORIZON_CONFIG = copy.copy(DEFAULT_CONFIG)
- HORIZON_CONFIG.update(settings.HORIZON_CONFIG)
-
- # Ensure we always have our exception configuration...
- for exc_category in ['unauthorized', 'not_found', 'recoverable']:
- if exc_category not in HORIZON_CONFIG['exceptions']:
- default_exc_config = DEFAULT_CONFIG['exceptions'][exc_category]
- HORIZON_CONFIG['exceptions'][exc_category] = default_exc_config
-
- # Ensure our password validator always exists...
- if 'regex' not in HORIZON_CONFIG['password_validator']:
- default_pw_regex = DEFAULT_CONFIG['password_validator']['regex']
- HORIZON_CONFIG['password_validator']['regex'] = default_pw_regex
- if 'help_text' not in HORIZON_CONFIG['password_validator']:
- default_pw_help = DEFAULT_CONFIG['password_validator']['help_text']
- HORIZON_CONFIG['password_validator']['help_text'] = default_pw_help
-
- self._wrapped = HORIZON_CONFIG
-
- def __getitem__(self, name, fallback=None):
- if self._wrapped is empty:
- self._setup(name)
- return self._wrapped.get(name, fallback)
-
-HORIZON_CONFIG = LazySettings()
diff --git a/horizon/conf/dash_template/__init__.py b/horizon/conf/dash_template/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/conf/dash_template/__init__.py
+++ /dev/null
diff --git a/horizon/conf/dash_template/dashboard.py.tmpl b/horizon/conf/dash_template/dashboard.py.tmpl
deleted file mode 100644
index 9e435bef..00000000
--- a/horizon/conf/dash_template/dashboard.py.tmpl
+++ /dev/null
@@ -1,13 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-
-class {{ dash_name|title }}(horizon.Dashboard):
- name = _("{{ dash_name|title }}")
- slug = "{{ dash_name|slugify }}"
- panels = () # Add your panels here.
- default_panel = '' # Specify the slug of the dashboard's default panel.
-
-
-horizon.register({{ dash_name|title }})
diff --git a/horizon/conf/dash_template/models.py b/horizon/conf/dash_template/models.py
deleted file mode 100644
index 1b3d5f9e..00000000
--- a/horizon/conf/dash_template/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/horizon/conf/dash_template/static/dash_name/css/dash_name.css b/horizon/conf/dash_template/static/dash_name/css/dash_name.css
deleted file mode 100644
index ed03b4f6..00000000
--- a/horizon/conf/dash_template/static/dash_name/css/dash_name.css
+++ /dev/null
@@ -1 +0,0 @@
-/* Additional CSS for {{ dash_name }}. */
diff --git a/horizon/conf/dash_template/static/dash_name/js/dash_name.js b/horizon/conf/dash_template/static/dash_name/js/dash_name.js
deleted file mode 100644
index a8088523..00000000
--- a/horizon/conf/dash_template/static/dash_name/js/dash_name.js
+++ /dev/null
@@ -1 +0,0 @@
-/* Additional JavaScript for {{ dash_name }}. */
diff --git a/horizon/conf/dash_template/templates/dash_name/base.html b/horizon/conf/dash_template/templates/dash_name/base.html
deleted file mode 100644
index f07a01ba..00000000
--- a/horizon/conf/dash_template/templates/dash_name/base.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% load horizon %}{% jstemplate %}[% extends 'base.html' %]
-
-[% block sidebar %]
- [% include 'horizon/common/_sidebar.html' %]
-[% endblock %]
-
-[% block main %]
- [% include "horizon/_messages.html" %]
- [% block {{ dash_name }}_main %][% endblock %]
-[% endblock %]
-{% endjstemplate %}
diff --git a/horizon/conf/default.py b/horizon/conf/default.py
deleted file mode 100644
index 445b2571..00000000
--- a/horizon/conf/default.py
+++ /dev/null
@@ -1,35 +0,0 @@
-from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
-
-# Default configuration dictionary. Do not mutate.
-HORIZON_CONFIG = {
- # Allow for ordering dashboards; list or tuple if provided.
- 'dashboards': None,
-
- # Name of a default dashboard; defaults to first alphabetically if None
- 'default_dashboard': None,
-
- # Default redirect url for users' home
- 'user_home': settings.LOGIN_REDIRECT_URL,
-
- # AJAX settings for JavaScript
- 'ajax_queue_limit': 10,
- 'ajax_poll_interval': 2500,
-
- # URL for additional help with this site.
- 'help_url': None,
-
- # Exception configuration.
- 'exceptions': {'unauthorized': [],
- 'not_found': [],
- 'recoverable': []},
-
- # Password configuration.
- 'password_validator': {'regex': '.*',
- 'help_text': _("Password is not accepted")},
-
- 'password_autocomplete': 'on',
-
- # Enable or disable simplified floating IP address management.
- 'simple_ip_management': True
-}
diff --git a/horizon/conf/panel_template/__init__.py b/horizon/conf/panel_template/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/conf/panel_template/__init__.py
+++ /dev/null
diff --git a/horizon/conf/panel_template/models.py b/horizon/conf/panel_template/models.py
deleted file mode 100644
index 1b3d5f9e..00000000
--- a/horizon/conf/panel_template/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/horizon/conf/panel_template/panel.py.tmpl b/horizon/conf/panel_template/panel.py.tmpl
deleted file mode 100644
index 4364438e..00000000
--- a/horizon/conf/panel_template/panel.py.tmpl
+++ /dev/null
@@ -1,13 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from {{ dash_path }} import dashboard
-
-
-class {{ panel_name|title }}(horizon.Panel):
- name = _("{{ panel_name|title }}")
- slug = "{{ panel_name|slugify }}"
-
-
-dashboard.{{ dash_name|title }}.register({{ panel_name|title }})
diff --git a/horizon/conf/panel_template/templates/panel_name/index.html b/horizon/conf/panel_template/templates/panel_name/index.html
deleted file mode 100644
index 5185396b..00000000
--- a/horizon/conf/panel_template/templates/panel_name/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% load horizon %}{% jstemplate %}[% extends '{{ dash_name }}/base.html' %]
-[% load i18n %]
-[% block title %][% trans "{{ panel_name|title }}" %][% endblock %]
-
-[% block page_header %]
- [% include "horizon/common/_page_header.html" with title=_("{{ panel_name|title }}") %]
-[% endblock page_header %]
-
-[% block {{ dash_name }}_main %]
-[% endblock %]
-
-{% endjstemplate %}
diff --git a/horizon/conf/panel_template/tests.py.tmpl b/horizon/conf/panel_template/tests.py.tmpl
deleted file mode 100644
index e8bba98c..00000000
--- a/horizon/conf/panel_template/tests.py.tmpl
+++ /dev/null
@@ -1,7 +0,0 @@
-from horizon.test import helpers as test
-
-
-class {{ panel_name|title}}Tests(test.TestCase):
- # Unit tests for {{ panel_name }}.
- def test_me(self):
- self.assertTrue(1 + 1 == 2)
diff --git a/horizon/conf/panel_template/urls.py b/horizon/conf/panel_template/urls.py
deleted file mode 100644
index b549cca5..00000000
--- a/horizon/conf/panel_template/urls.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from django.conf.urls.defaults import patterns, url
-
-from .views import IndexView
-
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
-)
diff --git a/horizon/conf/panel_template/views.py b/horizon/conf/panel_template/views.py
deleted file mode 100644
index a5116ca4..00000000
--- a/horizon/conf/panel_template/views.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from horizon import views
-
-
-class IndexView(views.APIView):
- # A very simple class-based view...
- template_name = '{{ dash_name }}/{{ panel_name }}/index.html'
-
- def get_data(self, request, context, *args, **kwargs):
- # Add data to the context here...
- return context
diff --git a/horizon/context_processors.py b/horizon/context_processors.py
deleted file mode 100644
index f5d2ecfd..00000000
--- a/horizon/context_processors.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-"""
-Context processors used by Horizon.
-"""
-
-from horizon import conf
-
-
-def horizon(request):
- """ The main Horizon context processor. Required for Horizon to function.
-
- It adds the Horizon config to the context as well as setting the names
- ``True`` and ``False`` in the context to their boolean equivalents
- for convenience.
-
- .. warning::
-
- Don't put API calls in context processors; they will be called once
- for each template/template fragment which takes context that is used
- to render the complete output.
- """
- context = {"HORIZON_CONFIG": conf.HORIZON_CONFIG,
- "True": True,
- "False": False}
-
- return context
diff --git a/horizon/decorators.py b/horizon/decorators.py
deleted file mode 100644
index f4d41092..00000000
--- a/horizon/decorators.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 CRS4
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-General-purpose decorators for use with Horizon.
-"""
-import functools
-
-from django.utils.decorators import available_attrs
-from django.utils.translation import ugettext_lazy as _
-
-
-def _current_component(view_func, dashboard=None, panel=None):
- """ Sets the currently-active dashboard and/or panel on the request. """
- @functools.wraps(view_func, assigned=available_attrs(view_func))
- def dec(request, *args, **kwargs):
- if dashboard:
- request.horizon['dashboard'] = dashboard
- if panel:
- request.horizon['panel'] = panel
- return view_func(request, *args, **kwargs)
- return dec
-
-
-def require_auth(view_func):
- """ Performs user authentication check.
-
- Similar to Django's `login_required` decorator, except that this throws
- :exc:`~horizon.exceptions.NotAuthenticated` exception if the user is not
- signed-in.
- """
- from horizon.exceptions import NotAuthenticated
-
- @functools.wraps(view_func, assigned=available_attrs(view_func))
- def dec(request, *args, **kwargs):
- if request.user.is_authenticated():
- return view_func(request, *args, **kwargs)
- raise NotAuthenticated(_("Please log in to continue."))
- return dec
-
-
-def require_perms(view_func, required):
- """ Enforces permission-based access controls.
-
- :param list required: A tuple of permission names, all of which the request
- user must possess in order access the decorated view.
-
- Example usage::
-
- from horizon.decorators import require_perms
-
-
- @require_perms(['foo.admin', 'foo.member'])
- def my_view(request):
- ...
-
- Raises a :exc:`~horizon.exceptions.NotAuthorized` exception if the
- requirements are not met.
- """
- from horizon.exceptions import NotAuthorized
- # We only need to check each permission once for a view, so we'll use a set
- current_perms = getattr(view_func, '_required_perms', set([]))
- view_func._required_perms = current_perms | set(required)
-
- @functools.wraps(view_func, assigned=available_attrs(view_func))
- def dec(request, *args, **kwargs):
- if request.user.is_authenticated():
- if request.user.has_perms(view_func._required_perms):
- return view_func(request, *args, **kwargs)
- raise NotAuthorized(_("You are not authorized to access %s")
- % request.path)
-
- # If we don't have any permissions, just return the original view.
- if required:
- return dec
- else:
- return view_func
diff --git a/horizon/exceptions.py b/horizon/exceptions.py
deleted file mode 100644
index a5d48497..00000000
--- a/horizon/exceptions.py
+++ /dev/null
@@ -1,321 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Exceptions raised by the Horizon code and the machinery for handling them.
-"""
-
-import logging
-import os
-import sys
-
-from django.contrib.auth import logout
-from django.core.management import color_style
-from django.http import HttpRequest
-from django.utils.translation import ugettext_lazy as _
-from django.views.debug import CLEANSED_SUBSTITUTE
-from django.views.debug import SafeExceptionReporterFilter
-
-from horizon.conf import HORIZON_CONFIG
-from horizon import messages
-
-LOG = logging.getLogger(__name__)
-
-
-class HorizonReporterFilter(SafeExceptionReporterFilter):
- """ Error report filter that's always active, even in DEBUG mode. """
- def is_active(self, request):
- return True
-
- # TODO(gabriel): This bugfix is cribbed from Django's code. When 1.4.1
- # is available we can remove this code.
- def get_traceback_frame_variables(self, request, tb_frame):
- """
- Replaces the values of variables marked as sensitive with
- stars (*********).
- """
- # Loop through the frame's callers to see if the sensitive_variables
- # decorator was used.
- current_frame = tb_frame.f_back
- sensitive_variables = None
- while current_frame is not None:
- if (current_frame.f_code.co_name == 'sensitive_variables_wrapper'
- and 'sensitive_variables_wrapper'
- in current_frame.f_locals):
- # The sensitive_variables decorator was used, so we take note
- # of the sensitive variables' names.
- wrapper = current_frame.f_locals['sensitive_variables_wrapper']
- sensitive_variables = getattr(wrapper,
- 'sensitive_variables',
- None)
- break
- current_frame = current_frame.f_back
-
- cleansed = []
- if self.is_active(request) and sensitive_variables:
- if sensitive_variables == '__ALL__':
- # Cleanse all variables
- for name, value in tb_frame.f_locals.items():
- cleansed.append((name, CLEANSED_SUBSTITUTE))
- return cleansed
- else:
- # Cleanse specified variables
- for name, value in tb_frame.f_locals.items():
- if name in sensitive_variables:
- value = CLEANSED_SUBSTITUTE
- elif isinstance(value, HttpRequest):
- # Cleanse the request's POST parameters.
- value = self.get_request_repr(value)
- cleansed.append((name, value))
- return cleansed
- else:
- # Potentially cleanse only the request if it's one of the
- # frame variables.
- for name, value in tb_frame.f_locals.items():
- if isinstance(value, HttpRequest):
- # Cleanse the request's POST parameters.
- value = self.get_request_repr(value)
- cleansed.append((name, value))
- return cleansed
-
-
-class HorizonException(Exception):
- """ Base exception class for distinguishing our own exception classes. """
- pass
-
-
-class Http302(HorizonException):
- """
- Error class which can be raised from within a handler to cause an
- early bailout and redirect at the middleware level.
- """
- status_code = 302
-
- def __init__(self, location, message=None):
- self.location = location
- self.message = message
-
-
-class NotAuthorized(HorizonException):
- """
- Raised whenever a user attempts to access a resource which they do not
- have permission-based access to (such as when failing the
- :func:`~horizon.decorators.require_perms` decorator).
-
- The included :class:`~horizon.middleware.HorizonMiddleware` catches
- ``NotAuthorized`` and handles it gracefully by displaying an error
- message and redirecting the user to a login page.
- """
- status_code = 401
-
-
-class NotAuthenticated(HorizonException):
- """
- Raised when a user is trying to make requests and they are not logged in.
-
- The included :class:`~horizon.middleware.HorizonMiddleware` catches
- ``NotAuthenticated`` and handles it gracefully by displaying an error
- message and redirecting the user to a login page.
- """
- status_code = 403
-
-
-class NotFound(HorizonException):
- """ Generic error to replace all "Not Found"-type API errors. """
- status_code = 404
-
-
-class RecoverableError(HorizonException):
- """ Generic error to replace any "Recoverable"-type API errors. """
- status_code = 100 # HTTP status code "Continue"
-
-
-class ServiceCatalogException(HorizonException):
- """
- Raised when a requested service is not available in the ``ServiceCatalog``
- returned by Keystone.
- """
- def __init__(self, service_name):
- message = 'Invalid service catalog service: %s' % service_name
- super(ServiceCatalogException, self).__init__(message)
-
-
-class AlreadyExists(HorizonException):
- """
- Exception to be raised when trying to create an API resource which
- already exists.
- """
- def __init__(self, name, resource_type):
- self.attrs = {"name": name, "resource": resource_type}
- self.msg = 'A %(resource)s with the name "%(name)s" already exists.'
-
- def __repr__(self):
- return self.msg % self.attrs
-
- def __str__(self):
- return self.msg % self.attrs
-
- def __unicode__(self):
- return _(self.msg) % self.attrs
-
-
-class WorkflowError(HorizonException):
- """ Exception to be raised when something goes wrong in a workflow. """
- pass
-
-
-class WorkflowValidationError(HorizonException):
- """
- Exception raised during workflow validation if required data is missing,
- or existing data is not valid.
- """
- pass
-
-
-class HandledException(HorizonException):
- """
- Used internally to track exceptions that have gone through
- :func:`horizon.exceptions.handle` more than once.
- """
- def __init__(self, wrapped):
- self.wrapped = wrapped
-
-
-UNAUTHORIZED = tuple(HORIZON_CONFIG['exceptions']['unauthorized'])
-NOT_FOUND = tuple(HORIZON_CONFIG['exceptions']['not_found'])
-RECOVERABLE = (AlreadyExists,)
-RECOVERABLE += tuple(HORIZON_CONFIG['exceptions']['recoverable'])
-
-
-def error_color(msg):
- return color_style().ERROR_OUTPUT(msg)
-
-
-def check_message(keywords, message):
- """
- Checks an exception for given keywords and raises a new ``ActionError``
- with the desired message if the keywords are found. This allows selective
- control over API error messages.
- """
- exc_type, exc_value, exc_traceback = sys.exc_info()
- if set(str(exc_value).split(" ")).issuperset(set(keywords)):
- exc_value._safe_message = message
- raise
-
-
-def handle(request, message=None, redirect=None, ignore=False,
- escalate=False, log_level=None, force_log=None):
- """ Centralized error handling for Horizon.
-
- Because Horizon consumes so many different APIs with completely
- different ``Exception`` types, it's necessary to have a centralized
- place for handling exceptions which may be raised.
-
- Exceptions are roughly divided into 3 types:
-
- #. ``UNAUTHORIZED``: Errors resulting from authentication or authorization
- problems. These result in being logged out and sent to the login screen.
- #. ``NOT_FOUND``: Errors resulting from objects which could not be
- located via the API. These generally result in a user-facing error
- message, but are otherwise returned to the normal code flow. Optionally
- a redirect value may be passed to the error handler so users are
- returned to a different view than the one requested in addition to the
- error message.
- #. RECOVERABLE: Generic API errors which generate a user-facing message
- but drop directly back to the regular code flow.
-
- All other exceptions bubble the stack as normal unless the ``ignore``
- argument is passed in as ``True``, in which case only unrecognized
- errors are bubbled.
-
- If the exception is not re-raised, an appropriate wrapper exception
- class indicating the type of exception that was encountered will be
- returned.
- """
- exc_type, exc_value, exc_traceback = sys.exc_info()
- log_method = getattr(LOG, log_level or "exception")
- force_log = force_log or os.environ.get("HORIZON_TEST_RUN", False)
- force_silence = getattr(exc_value, "silence_logging", False)
-
- # Because the same exception may travel through this method more than
- # once (if it's re-raised) we may want to treat it differently
- # the second time (e.g. no user messages/logging).
- handled = issubclass(exc_type, HandledException)
- wrap = False
-
- # Restore our original exception information, but re-wrap it at the end
- if handled:
- exc_type, exc_value, exc_traceback = exc_value.wrapped
- wrap = True
-
- # We trust messages from our own exceptions
- if issubclass(exc_type, HorizonException):
- message = exc_value
- # Check for an override message
- elif getattr(exc_value, "_safe_message", None):
- message = exc_value._safe_message
- # If the message has a placeholder for the exception, fill it in
- elif message and "%(exc)s" in message:
- message = message % {"exc": exc_value}
-
- if issubclass(exc_type, UNAUTHORIZED):
- if ignore:
- return NotAuthorized
- if not force_silence and not handled:
- log_method(error_color("Unauthorized: %s" % exc_value))
- if not handled:
- if message:
- message = _("Unauthorized: %s") % message
- # We get some pretty useless error messages back from
- # some clients, so let's define our own fallback.
- fallback = _("Unauthorized. Please try logging in again.")
- messages.error(request, message or fallback)
- # Escalation means logging the user out and raising NotAuthorized
- # so the middleware will redirect them appropriately.
- if escalate:
- logout(request)
- raise NotAuthorized
- # Otherwise continue and present our "unauthorized" error message.
- return NotAuthorized
-
- if issubclass(exc_type, NOT_FOUND):
- wrap = True
- if not force_silence and not handled and (not ignore or force_log):
- log_method(error_color("Not Found: %s" % exc_value))
- if not ignore and not handled:
- messages.error(request, message or exc_value)
- if redirect:
- raise Http302(redirect)
- if not escalate:
- return NotFound # return to normal code flow
-
- if issubclass(exc_type, RECOVERABLE):
- wrap = True
- if not force_silence and not handled and (not ignore or force_log):
- # Default recoverable error to WARN log level
- log_method = getattr(LOG, log_level or "warning")
- log_method(error_color("Recoverable error: %s" % exc_value))
- if not ignore and not handled:
- messages.error(request, message or exc_value)
- if redirect:
- raise Http302(redirect)
- if not escalate:
- return RecoverableError # return to normal code flow
-
- # If we've gotten here, time to wrap and/or raise our exception.
- if wrap:
- raise HandledException([exc_type, exc_value, exc_traceback])
- raise exc_type, exc_value, exc_traceback
diff --git a/horizon/forms/__init__.py b/horizon/forms/__init__.py
deleted file mode 100644
index 55135846..00000000
--- a/horizon/forms/__init__.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# FIXME(gabriel): Legacy imports for API compatibility.
-from django.forms import * # noqa
-from django.forms import widgets
-
-# Convenience imports for public API components.
-from horizon.forms.base import DateForm
-from horizon.forms.base import SelfHandlingForm
-from horizon.forms.base import SelfHandlingMixin
-from horizon.forms.fields import DynamicChoiceField
-from horizon.forms.fields import DynamicTypedChoiceField
-# FIXME: TableStep hack adding NumberInput
-from horizon.forms.fields import NumberInput
-from horizon.forms.views import ModalFormMixin
-from horizon.forms.views import ModalFormView
-
-assert widgets
-assert SelfHandlingMixin
-assert SelfHandlingForm
-assert DateForm
-assert ModalFormView
-assert ModalFormMixin
-assert DynamicTypedChoiceField
-assert DynamicChoiceField
-assert NumberInput
diff --git a/horizon/forms/base.py b/horizon/forms/base.py
deleted file mode 100644
index aa6b0232..00000000
--- a/horizon/forms/base.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django import forms
-from django.forms.forms import NON_FIELD_ERRORS
-
-
-class SelfHandlingMixin(object):
- def __init__(self, request, *args, **kwargs):
- self.request = request
- if not hasattr(self, "handle"):
- raise NotImplementedError("%s does not define a handle method."
- % self.__class__.__name__)
- super(SelfHandlingMixin, self).__init__(*args, **kwargs)
-
-
-class SelfHandlingForm(SelfHandlingMixin, forms.Form):
- """
- A base :class:`Form <django:django.forms.Form>` class which includes
- processing logic in its subclasses.
- """
- def api_error(self, message):
- """
- Adds an error to the form's error dictionary after validation
- based on problems reported via the API. This is useful when you
- wish for API errors to appear as errors on the form rather than
- using the messages framework.
- """
- self._errors[NON_FIELD_ERRORS] = self.error_class([message])
-
-
-class DateForm(forms.Form):
- """ A simple form for selecting a range of time. """
- start = forms.DateField(input_formats=("%Y-%m-%d",))
- end = forms.DateField(input_formats=("%Y-%m-%d",))
-
- def __init__(self, *args, **kwargs):
- super(DateForm, self).__init__(*args, **kwargs)
- self.fields['start'].widget.attrs['data-date-format'] = "yyyy-mm-dd"
- self.fields['end'].widget.attrs['data-date-format'] = "yyyy-mm-dd"
diff --git a/horizon/forms/fields.py b/horizon/forms/fields.py
deleted file mode 100644
index 9bfcc465..00000000
--- a/horizon/forms/fields.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core import urlresolvers
-from django.forms import fields
-from django.forms import widgets
-
-
-class DynamicSelectWidget(widgets.Select):
- """
- A subclass of the ``Select`` widget which renders extra attributes for use
- in callbacks to handle dynamic changes to the available choices.
- """
- _data_add_url_attr = "data-add-item-url"
-
- def render(self, *args, **kwargs):
- add_item_url = self.get_add_item_url()
- if add_item_url is not None:
- self.attrs.update({self._data_add_url_attr: add_item_url})
- return super(DynamicSelectWidget, self).render(*args, **kwargs)
-
- def get_add_item_url(self):
- if callable(self.add_item_link):
- return self.add_item_link()
- try:
- if self.add_item_link_args:
- return urlresolvers.reverse(self.add_item_link,
- args=[self.add_item_link_args])
- else:
- return urlresolvers.reverse(self.add_item_link)
- except urlresolvers.NoReverseMatch:
- return self.add_item_link
-
-
-class DynamicChoiceField(fields.ChoiceField):
- """
- A subclass of ``ChoiceField`` with additional properties that make
- dynamically updating its elements easier.
-
- Notably, the field declaration takes an extra argument, ``add_item_link``
- which may be a string or callable defining the URL that should be used
- for the "add" link associated with the field.
- """
- widget = DynamicSelectWidget
-
- def __init__(self,
- add_item_link=None,
- add_item_link_args=None,
- *args,
- **kwargs):
- super(DynamicChoiceField, self).__init__(*args, **kwargs)
- self.widget.add_item_link = add_item_link
- self.widget.add_item_link_args = add_item_link_args
-
-
-class DynamicTypedChoiceField(DynamicChoiceField, fields.TypedChoiceField):
- """ Simple mix of ``DynamicChoiceField`` and ``TypedChoiceField``. """
- pass
-
-
-# FIXME: TableStep
-# Should be in django 1.5.1 forms.widgets
-class NumberInput(widgets.TextInput):
- input_type = 'number'
diff --git a/horizon/forms/views.py b/horizon/forms/views.py
deleted file mode 100644
index b37c4d25..00000000
--- a/horizon/forms/views.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import json
-import os
-
-from django import http
-from django.views import generic
-
-from horizon import exceptions
-
-
-ADD_TO_FIELD_HEADER = "HTTP_X_HORIZON_ADD_TO_FIELD"
-
-
-class ModalFormMixin(object):
- def get_template_names(self):
- if self.request.is_ajax():
- if not hasattr(self, "ajax_template_name"):
- # Transform standard template name to ajax name (leading "_")
- bits = list(os.path.split(self.template_name))
- bits[1] = "".join(("_", bits[1]))
- self.ajax_template_name = os.path.join(*bits)
- template = self.ajax_template_name
- else:
- template = self.template_name
- return template
-
- def get_context_data(self, **kwargs):
- context = super(ModalFormMixin, self).get_context_data(**kwargs)
- if self.request.is_ajax():
- context['hide'] = True
- if ADD_TO_FIELD_HEADER in self.request.META:
- context['add_to_field'] = self.request.META[ADD_TO_FIELD_HEADER]
- return context
-
-
-class ModalFormView(ModalFormMixin, generic.FormView):
- """
- The main view class from which all views which handle forms in Horizon
- should inherit. It takes care of all details with processing
- :class:`~horizon.forms.base.SelfHandlingForm` classes, and modal concerns
- when the associated template inherits from
- `horizon/common/_modal_form.html`.
-
- Subclasses must define a ``form_class`` and ``template_name`` attribute
- at minimum.
-
- See Django's documentation on the `FormView <https://docs.djangoproject.com
- /en/dev/ref/class-based-views/generic-editing/#formview>`_ class for
- more details.
- """
-
- def get_object_id(self, obj):
- """
- For dynamic insertion of resources created in modals, this method
- returns the id of the created object. Defaults to returning the ``id``
- attribute.
- """
- return obj.id
-
- def get_object_display(self, obj):
- """
- For dynamic insertion of resources created in modals, this method
- returns the display name of the created object. Defaults to returning
- the ``name`` attribute.
- """
- return obj.name
-
- def get_form(self, form_class):
- """
- Returns an instance of the form to be used in this view.
- """
- return form_class(self.request, **self.get_form_kwargs())
-
- def form_valid(self, form):
- try:
- handled = form.handle(self.request, form.cleaned_data)
- except:
- handled = None
- exceptions.handle(self.request)
-
- if handled:
- if ADD_TO_FIELD_HEADER in self.request.META:
- field_id = self.request.META[ADD_TO_FIELD_HEADER]
- data = [self.get_object_id(handled),
- self.get_object_display(handled)]
- response = http.HttpResponse(json.dumps(data))
- response["X-Horizon-Add-To-Field"] = field_id
- elif isinstance(handled, http.HttpResponse):
- return handled
- else:
- success_url = self.get_success_url()
- response = http.HttpResponseRedirect(success_url)
- # TODO(gabriel): This is not a long-term solution to how
- # AJAX should be handled, but it's an expedient solution
- # until the blueprint for AJAX handling is architected
- # and implemented.
- response['X-Horizon-Location'] = success_url
- return response
- else:
- # If handled didn't return, we can assume something went
- # wrong, and we should send back the form as-is.
- return self.form_invalid(form)
diff --git a/horizon/loaders.py b/horizon/loaders.py
deleted file mode 100644
index 6ab86b8f..00000000
--- a/horizon/loaders.py
+++ /dev/null
@@ -1,48 +0,0 @@
-"""
-Wrapper for loading templates from "templates" directories in panel modules.
-"""
-
-import os
-
-from django.conf import settings
-from django.template.base import TemplateDoesNotExist
-from django.template.loader import BaseLoader
-from django.utils._os import safe_join
-
-# Set up a cache of the panel directories to search.
-panel_template_dirs = {}
-
-
-class TemplateLoader(BaseLoader):
- is_usable = True
-
- def get_template_sources(self, template_name):
- bits = template_name.split(os.path.sep, 2)
- if len(bits) == 3:
- dash_name, panel_name, remainder = bits
- key = os.path.join(dash_name, panel_name)
- if key in panel_template_dirs:
- template_dir = panel_template_dirs[key]
- try:
- yield safe_join(template_dir, panel_name, remainder)
- except UnicodeDecodeError:
- # The template dir name wasn't valid UTF-8.
- raise
- except ValueError:
- # The joined path was located outside of template_dir.
- pass
-
- def load_template_source(self, template_name, template_dirs=None):
- for path in self.get_template_sources(template_name):
- try:
- file = open(path)
- try:
- return (file.read().decode(settings.FILE_CHARSET), path)
- finally:
- file.close()
- except IOError:
- pass
- raise TemplateDoesNotExist(template_name)
-
-
-_loader = TemplateLoader()
diff --git a/horizon/locale/bg_BG/LC_MESSAGES/django.mo b/horizon/locale/bg_BG/LC_MESSAGES/django.mo
deleted file mode 100644
index 59683721..00000000
--- a/horizon/locale/bg_BG/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/bg_BG/LC_MESSAGES/django.po b/horizon/locale/bg_BG/LC_MESSAGES/django.po
deleted file mode 100644
index 1dab121c..00000000
--- a/horizon/locale/bg_BG/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,514 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Dimitar Dimitrov <dimitrov@linuxmail.org>, 2012
-# Yasen Pramatarov <yasen@lindeas.com>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: bg_BG\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Друго"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Влезте, за да продължите."
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "Нямате права да достъпвате %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Нямате права. Опитайте да влезете отново."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr ""
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "Паролата не е одобрена."
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Филтър"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr ""
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr ""
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "Нямате права да %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Изтриване"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Изтрито"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr ""
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr ""
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Действия"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr ""
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Изберете ред, преди да предприемете това действие."
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "Помощ"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "Изход"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "Вход"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "Вход"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr ""
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "Записване"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Информация: "
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Внимание: "
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Успех: "
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Грешка: "
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "Обобщение"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "Обобщение"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr "Всички инстанции"
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "Налично"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "Налично"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "Текущ проект"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "Изберете месец, за да намерите потреблението"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "Изпращане"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Активни инстанции"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr ""
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Отказ"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr ""
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "Без ограничение"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Налично"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "Паролата трябва да е между 8 и 18 символа."
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Котки"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Котенца"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Тигри"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Кучета"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Кученца"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "Моето табло"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "Моят панел"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Админ панел"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "Грамадни мравки нападат Сан Франциско!"
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr ""
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr ""
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr ""
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr ""
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr ""
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr ""
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr ""
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr ""
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr ""
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr ""
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr ""
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Проект"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "Потребител"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Пръбно действие първо"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Инстанция"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Пробно действие второ"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Пробно действие трето"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Админ"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Администраторско действие"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Неправилен формат на IP-адрес"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Неправилна версия на IP-адрес"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Неправилна маска на подмрежата"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Обработване..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Запазване"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s приключи успешно."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s не приключи."
diff --git a/horizon/locale/bg_BG/LC_MESSAGES/djangojs.mo b/horizon/locale/bg_BG/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 8b5ad21b..00000000
--- a/horizon/locale/bg_BG/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/bg_BG/LC_MESSAGES/djangojs.po b/horizon/locale/bg_BG/LC_MESSAGES/djangojs.po
deleted file mode 100644
index 65b0ef3e..00000000
--- a/horizon/locale/bg_BG/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,73 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/ca/LC_MESSAGES/django.mo b/horizon/locale/ca/LC_MESSAGES/django.mo
deleted file mode 100644
index 15411809..00000000
--- a/horizon/locale/ca/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/ca/LC_MESSAGES/django.po b/horizon/locale/ca/LC_MESSAGES/django.po
deleted file mode 100644
index 4e7bd990..00000000
--- a/horizon/locale/ca/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,513 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Sergi Almacellas <pokoli@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ca\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Altre"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Identifique-se per continuar."
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "No esteu autoritzat per accedir a %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Sense autorització. Torneu a intentar-ho."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr ""
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "La contrasenya no ha estat acceptada"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Filtre"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr ""
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr ""
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "No teniu per misos per a %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "No es pot %(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Eliminar"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Eliminat"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "L'attribut %(attr)s no existeix a %(obj)s"
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "No hi ha itemas per mostrar"
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Accions"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "No hi ha resultats per l'identificador \"%s\"."
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Heu de seleccionar una fila abans de dur a terme aquesta acció."
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Identificat com"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "Ajuda"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "Sortir"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "Usuari"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "Identificació"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr ""
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "Registrar-se"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Informació:"
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Advertència:"
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Èxit:"
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Error: "
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "Resum"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "Mostrant %(counter)s element"
-msgstr[1] "Mostrar %(counter)s elements"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "Resum"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "Usat"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr "de"
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr "Totes les instàncies"
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "Disponible"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "Disponible"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] "Mostrant %(nav_items)s objjecte"
-msgstr[1] "Mostrant %(nav_items)s objjectes"
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] "Mostrant %(content_items)s objjecte"
-msgstr[1] "Mostrant %(content_items)s objjectes"
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "Projecte actual"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "Seleccioneu un mes per obtenir les seves estadístiques d'us"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "Transmet"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Activar instàncies"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr "Memòria activa"
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "Hores de VCPU d'aquest més"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "GB-Hores d'aquest més"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Cancela"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "Horizon"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "Sense limit"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Disponible"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d byte"
-msgstr[1] "%(size)d bytes"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-msgstr[1] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "La contrasenya ha de tenir entre 8 i 18 caràcters."
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr ""
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr ""
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr ""
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr ""
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "El meu tauler de control"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "El meu tauler"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Tauler d'administració"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr ""
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "Lot"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "En lots"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "Item"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "Items"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "Davall"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "Amunt"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "Baixat"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "Pujat"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr ""
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "Primera pestanya"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "Pestanya retardada"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "Pestanya deshabilitada"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "Pestanya enraderida"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "Pestanya amb la meua taula"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "Pestanya d'error recuperables"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Projecte"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "Usuari"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Acció de prova 1"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Instància"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Acció de prova 2"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Acció de prova 3"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Adminstració"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Acció de l'administració"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Format incorrecte per l'adreça IP"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Versió incorrecta de l'adreça IP"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Màscara de xarxa invàlida"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Processant..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Desa"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s completat correctament."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s no s'ha completat"
diff --git a/horizon/locale/cs/LC_MESSAGES/django.mo b/horizon/locale/cs/LC_MESSAGES/django.mo
deleted file mode 100644
index 2e0935c7..00000000
--- a/horizon/locale/cs/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/cs/LC_MESSAGES/django.po b/horizon/locale/cs/LC_MESSAGES/django.po
deleted file mode 100644
index b5501583..00000000
--- a/horizon/locale/cs/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,520 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# _AdamCz_ <a.skotnicky@tcpisek.cz>, 2013
-# pavlija7 <pavlk.jakub@gmail.com>, 2013
-# Jaroslav Henner <jaroslav.henner@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: cs\n"
-"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Ostatní"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "K pokračování je nutno se přihlásit."
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "Nejste autorizován k přístupu %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Nejste autorizován. Prosím pokuste se přihlásit znovu."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr "Navigační položka"
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr "Vyberte %s pro prohlížení"
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "Heslo nebylo akceptováno"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Filtr"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr "%(action)s %(data_type)s"
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr "nedostupné"
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "Nemáte oprávnění pro %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "Není možné provést %(action)s na %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Vymazat"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Smazáno"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "Atribut %(attr)s neexistuje na %(obj)s."
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "Žádné položky k zobrazení."
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Akce"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "Nic s id \"%s\" nebylo nalezeno."
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Pro provedení akce prosím vyberte řádky."
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Přihlášen jako"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "Nápověda"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "Odhlásit"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "Přihlášení"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "Přihlásit"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr "Nemáte povolení pro přístup k:"
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr "Přihlašte se jako jiný uživatel nebo se vraťte k"
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr "domovská stránka"
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "Registrovat"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Info:"
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Varování:"
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Úspěch:"
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Chyba:"
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "Souhrn"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "Zobrazuji %(counter)s položku"
-msgstr[1] "Zobrazuji %(counter)s položek"
-msgstr[2] "Zobrazuji %(counter)s položky"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr "Více"
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "Souhrn kvóty"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "Použito"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr "z"
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr "Dostupné instance"
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "Dostupné vCPU"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "Dostupná RAM"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr "Dostupné volumes"
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr "Dostupný diskový prostor"
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] "Zobrazuji %(nav_items)s položku"
-msgstr[1] "Zobrazuji %(nav_items)s položky"
-msgstr[2] "Zobrazuji %(nav_items)s položky"
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] "Zobrazuji %(content_items)s položku"
-msgstr[1] "Zobrazuji %(content_items)s položky"
-msgstr[2] "Zobrazuji %(content_items)s položky"
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "Současný projekt"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "Vyberte měsíc pro zobrazení jeho využití."
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "Potvrdit"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Aktivní instance"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr "Využívaná RAM"
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "VCPU-hodin za tento měsíc"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "GB-hodiny za tento měsíc"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Zrušit"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "Horizon"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "Bez limitu"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Dostupné"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d byte"
-msgstr[1] "%(size)d bytes"
-msgstr[2] "%(size)d bytes"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-msgstr[1] "%(size)d"
-msgstr[2] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "Heslo musí mít od 8 do 18 znaků."
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "Roztomilé kočky"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "Divoké kočky"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Kočky"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Koťata"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Tygři"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Psi"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Štěňata"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "Můj Dashboard"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "Můj panel"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Admin panel"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "Obří mravenci utočí na San Francisco!"
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr "Už jsme v bezpečí před maravenci! Běž <a>sem</a>!"
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "Dávka"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "Dávkově"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "Položka"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "Položek"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "Dolů"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "Nahoru"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "Sestřelený"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "Nahozený"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr "Žádná Action Table"
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr "Jedna tabulka"
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "Záložka jedna"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "Delayed Tab"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "Disabled Tab"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "Disallowed Tab"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "Záložka s My Table"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "Recoverable Error Tab"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Projekt"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "Uživatel"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Testovat Action One"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Instance"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Testovat Action Two"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Testovat Action Three"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Admin"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Admin akce"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Nekorektní formát IP adresy"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Špatná verze IP adresy"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Špatná subnet maska"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Zpracovávám..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr "Vše dostupné"
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr "Členové"
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr "Nedostupné"
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr "Žádní členové."
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Uložit"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s úspěšně dokončeno"
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s nedokončeno"
diff --git a/horizon/locale/en/LC_MESSAGES/django.mo b/horizon/locale/en/LC_MESSAGES/django.mo
deleted file mode 100644
index 5c6400d5..00000000
--- a/horizon/locale/en/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/en/LC_MESSAGES/django.po b/horizon/locale/en/LC_MESSAGES/django.po
deleted file mode 100644
index 09a23ae6..00000000
--- a/horizon/locale/en/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,514 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Gabriel Hurley <gabriel@strikeawe.com>, 2012
-# johnpostlethwait <john.postlethwait@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: en\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Other"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Please log in to continue."
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "You are not authorized to access %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Unauthorized. Please try logging in again."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr ""
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "Password is not accepted"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Filter"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr ""
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr ""
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "You do not have permission to %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "Unable to %(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Delete"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Deleted"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "The attribute %(attr)s doesn't exist on %(obj)s."
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "No items to display."
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Actions"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "No match returned for the id \"%s\"."
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Please select a row before taking that action."
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr ""
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr ""
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr ""
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr ""
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr ""
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Info: "
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Warning: "
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Success: "
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Error: "
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "Summary"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "Displaying %(counter)s item"
-msgstr[1] "Displaying %(counter)s items"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "Current Project"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "Select a month to query its usage"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "Submit"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Active Instances"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "This Month's VCPU-Hours"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "This Month's GB-Hours"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Cancel"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr ""
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "No Limit"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Available"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d byte"
-msgstr[1] "%(size)d bytes"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-msgstr[1] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "Password must be between 8 and 18 characters."
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "Cute Cats"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "Fierce Cats"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Cats"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Kittens"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Tigers"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Dogs"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Puppies"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "My Dashboard"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "My Panel"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Admin Panel"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "Giant ants are attacking San Francisco!"
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "Batch"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "Batched"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "Item"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "Items"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "Down"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "Up"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "Downed"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "Upped"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr ""
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "Tab One"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "Delayed Tab"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "Disabled Tab"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "Disallowed Tab"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "Tab With My Table"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "Recoverable Error Tab"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Project"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "User"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Test Action One"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Instance"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Test Action Two"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Test Action Three"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Admin"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Admin Action"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Incorrect format for IP address"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Invalid version for IP address"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Invalid subnet mask"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Processing..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Save"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s completed successfully."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s did not complete."
diff --git a/horizon/locale/en/LC_MESSAGES/djangojs.mo b/horizon/locale/en/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 8b5ad21b..00000000
--- a/horizon/locale/en/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/en/LC_MESSAGES/djangojs.po b/horizon/locale/en/LC_MESSAGES/djangojs.po
deleted file mode 100644
index 65b0ef3e..00000000
--- a/horizon/locale/en/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,73 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/en_GB/LC_MESSAGES/django.mo b/horizon/locale/en_GB/LC_MESSAGES/django.mo
deleted file mode 100644
index 816f1c44..00000000
--- a/horizon/locale/en_GB/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/en_GB/LC_MESSAGES/django.po b/horizon/locale/en_GB/LC_MESSAGES/django.po
deleted file mode 100644
index f5ea31e8..00000000
--- a/horizon/locale/en_GB/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,513 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Andi Chandler <andi@gowling.com>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-30 22:33+0000\n"
-"Last-Translator: Andi Chandler <andi@gowling.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: en_GB\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Other"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Please log in to continue."
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "You are not authorised to access %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Unauthorised. Please try logging in again."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr "Navigation Item"
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr "Select a %s to browse."
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "Password is not accepted"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Filter"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr "%(action)s %(data_type)s"
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr "N/A"
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "You do not have permission to %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "Unable to %(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Delete"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Deleted"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "The attribute %(attr)s does not exist on %(obj)s."
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "No items to display."
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Actions"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "No match returned for the id \"%s\"."
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Please select a row before taking that action."
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Logged in as"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "Help"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "Sign Out"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "Login"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "Log In"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr "You do not have permissions to access:"
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr "Login as different user or go back to"
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr "home page"
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "Sign In"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Info: "
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Warning: "
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Success: "
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Error: "
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "Summary"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr "More"
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "Quota Summary"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "Used"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr "of"
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr "Available Instances"
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "Available vCPUs"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "Available RAM"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr "Available volumes"
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr "Available volume storage"
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "Current Project"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "Select a month to query its usage"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "Submit"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Active Instances"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr "Active RAM"
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "This Month's VCPU-Hours"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "This Month's GB-Hours"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Cancel"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "Horizon"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "No Limit"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Available"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "Password must be between 8 and 18 characters."
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "Cute Cats"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "Fierce Cats"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Cats"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Kittens"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Tigers"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Dogs"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Puppies"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "My Dashboard"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "My Panel"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Admin Panel"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "Giant ants are attacking San Francisco!"
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr "We are now safe from ants! Go <a>here</a>!"
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "Batch"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "Batched"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "Item"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "Items"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "Down"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "Up"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "Downed"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "Upped"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr "No Actions Table"
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr "Single Table"
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "Tab One"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "Delayed Tab"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "Disabled Tab"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "Disallowed Tab"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "Tab With My Table"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "Recoverable Error Tab"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Project"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "User"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Test Action One"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Instance"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Test Action Two"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Test Action Three"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Admin"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Admin Action"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Incorrect format for IP address"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Invalid version for IP address"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Invalid subnet mask"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Processing..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr "All available"
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr "Members"
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr "None available."
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr "No members."
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Save"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s completed successfully."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s did not complete."
diff --git a/horizon/locale/es/LC_MESSAGES/django.mo b/horizon/locale/es/LC_MESSAGES/django.mo
deleted file mode 100644
index e37bf22c..00000000
--- a/horizon/locale/es/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/es/LC_MESSAGES/django.po b/horizon/locale/es/LC_MESSAGES/django.po
deleted file mode 100644
index 61431e98..00000000
--- a/horizon/locale/es/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,518 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Alberto Molina Coballes <alb.molina@gmail.com>, 2012-2013
-# Alberto Molina Coballes <alb.molina@gmail.com>, 2012
-# emujicad <emujicad@gmail.com>, 2013
-# Gabriel Hurley <gabriel@strikeawe.com>, 2012
-# zeus <jonathan.abdiel@gmail.com>, 2012
-# Pedro Navarro Pérez <pednape@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: es\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Otro"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Por favor inicie sesión para continuar."
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "No está autorizado para acceder a %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "No autorizado. Por favor ingrese de nuevo."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr "Ítem de Navegación"
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr "Seleccionar una %s para navegar."
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "La contraseña no se ha aceptado"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Filtrar"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr "%(action)s %(data_type)s"
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr "N/A"
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "No tiene permiso para %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "No ha sido posible %(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Borrar"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Borrado"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "El atributo %(attr)s no existe en %(obj)s."
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "No hay ítems que mostrar"
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Acciones"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "Ninguna coincidencia para el id \"%s\"."
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Por favor, seleccione una fila antes de realizar la acción."
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Identificado como"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "Ayuda"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "Salir"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "Ingresar"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "Ingresar"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr "No tiene permisos para acceder:"
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr "Ingresar como otro usuario o volver"
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr "Inicio"
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "Darse de alta"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Info:"
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Aviso:"
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Correcto:"
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Error: "
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "Resumen"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "Mostrando %(counter)s item"
-msgstr[1] "Mostrando %(counter)s items"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr "Más"
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "Resumen de cuotas"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "Usado"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr "de"
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr "Instancias disponibles"
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "vCPUs disponibles"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "RAM Disponible"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr "Volúmenes disponibles"
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr "Almacenamiento de volúmenes disponible"
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] "Mostrando %(nav_items)s item"
-msgstr[1] "Mostrando %(nav_items)s ítems"
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] "Mostrando %(content_items)s item"
-msgstr[1] "Mostrando %(content_items)s ítems"
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "Proyecto Actual"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "Seleccione un mes para el que solicitar uso"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "Enviar"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Instancias Activas"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr "RAM Activa"
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "Horas VCPU de este mes"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "Horas GB de este mes"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "Horizon"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "Sin límite"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Disponible"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d byte"
-msgstr[1] "%(size)d bytes"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-msgstr[1] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "La contraseña debe tener entre 8 y 18 caracteres."
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "Gatos bonitos"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "Gatos feroces"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Gatos"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Gatitos"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Tigres"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Perros"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Perritos"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "Mi Dashboard"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "Mi Panel"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Panel de Administración"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "¡Hormigas gigantes están atacando Sevilla!"
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr "¡Estamos a salvo de las hormigas! ¡Vaya <a>aquí</a>!"
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "Lote"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "Por lotes"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "Ítem"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "Ítems"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "Abajo"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "Arriba"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "Bajados"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "Subidos"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr "No hay tabla de acciones"
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr "Tabla única"
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "Pestaña Uno"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "Pestaña Retrasada"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "Pestaña Deshabilitada"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "Pestaña no Permitida"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "Pestaña con mi tabla"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "Pestaña de errores recuperables"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Proyecto"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "Usuario"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Acción de prueba Uno"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Instancia"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Acción de prueba Dos"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Acción de prueba Tres"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Admin"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Acción de Administrador"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Formato incorrecto de dirección IP"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Versión no válida de dirección IP"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Máscara de red no válida"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Procesando..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr "Todas disponibles"
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr "Miembros"
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr "Ninguna disponible."
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr "Sin miembros."
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Guardar"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s completado correctamente."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s no completado."
diff --git a/horizon/locale/es/LC_MESSAGES/djangojs.mo b/horizon/locale/es/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 2805f377..00000000
--- a/horizon/locale/es/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/es/LC_MESSAGES/djangojs.po b/horizon/locale/es/LC_MESSAGES/djangojs.po
deleted file mode 100644
index bceb2658..00000000
--- a/horizon/locale/es/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,74 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/fi_FI/LC_MESSAGES/django.mo b/horizon/locale/fi_FI/LC_MESSAGES/django.mo
deleted file mode 100644
index a1dd11f1..00000000
--- a/horizon/locale/fi_FI/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/fi_FI/LC_MESSAGES/django.po b/horizon/locale/fi_FI/LC_MESSAGES/django.po
deleted file mode 100644
index e8d2c178..00000000
--- a/horizon/locale/fi_FI/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,513 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# copard <ari.karhunen@pard.co>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-05-02 12:39+0000\n"
-"Last-Translator: copard <ari.karhunen@pard.co>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: fi_FI\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Toinen"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Kirjaudu jatkaaksesi"
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "Et ole oikeutettu päästäksesi %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Ei oikeutettu: Yritä kirjautumista uudelleen."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr "Navigaatio yksikkö"
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr "valitse %s selataksesi."
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "Salasanaa ei hyväksytty"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Filtteri"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr "%(action)s %(data_type)s"
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr "N/A"
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "Sinulla ei ole oikeuksia %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "Ei voida %(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Poista"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Poistettu"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "Arvoa %(attr)s ei löydy %(obj)s. "
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "Ei näytettävää."
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Toiminnot"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "ID \"%s\" ei palauttanut osumia."
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Valitse rivi ennen toiminnon tekemistä."
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Kirjauduttu käyttäjänä"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "Apua"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "Kirjaudu Ulos"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "Kirjaudu"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "Kirjaudu"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr "Teillä ei ole oikeuksia päästäksenne:"
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr "Kirjaudu toisena käyttäjänä palataksesi"
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr "kotisivu"
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "Kirjaudu"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Info:"
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Varoitus:"
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Onnistui:"
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Virhe:"
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "yhteenveto"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "Näytetään kohde %(counter)s "
-msgstr[1] "Näytetään %(counter)s kohdetta"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr "Lisää"
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "Kiintiö yleiskatsaus"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "käytetty"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr "kohteesta"
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr "Saatavilla olevat Instanssit"
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "Saatavilla olevat vCPU:t"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "Saatavilla oleva RAM"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr "Saatavilla olevat verkkolevyt"
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr "Saatavilla oleva verkkolevykapasiteetti"
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] "Näytetään %(nav_items)s kohde"
-msgstr[1] "Näytetään %(nav_items)s kohdetta"
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] "Näytetään %(content_items)s kohde"
-msgstr[1] "Näytetään %(content_items)s kohdetta"
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "Nykyinen projekti"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "Valitse kuukausi katsoaksesi käyttöä"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "Lähetä"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Aktivoi instanssit"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr "Käytetty RAM"
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "Tämän kuukauden VCPU-tunnit"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "Tämän kuukauden GB-tunnit"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Keskeytä"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "Horizon"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "Ei rajaa"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Saatavilla"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d tavu"
-msgstr[1] "%(size)d tavua"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-msgstr[1] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "Salasanan täytyy olla 8 ja 18 merkin väliltä."
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "meow meow kissat."
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "Hurjia kisuja"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Kisuja"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Pikku kisuja"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Tiikereitä roar."
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Koiria"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Pentuja. aww.."
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "Minun hallintapaneeli"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "Minun Paneeli"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Admin paneeli"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "YAY. Let the giant ants attack San FernandSisco."
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr "Olemme turvassa muurahaisilta, MENE <a>tänne</a>|"
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "Sarja"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "Sarjoitettu"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "kohta"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "kohdat"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "Alhaalla"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "Ylhäällä"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "Pudotettu"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "Nostettu"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr "Ei tehtävätauluja"
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr "Yksittäinen taulu"
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "Ensimmäinen Tab"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "Viivästetty Tab"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "Poistettu Tab"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "Estettu Tab"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "Tab minun taulussa"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "Palautettava Virhe Tab"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Projekti"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "Käyttäjä"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "ensimmäinen Testitoimi"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Insanssi"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "toinen testitoimi"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "kolmas testitoimi"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Admin"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Admin toimi"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Väärä formaatti IP-osoitteelle."
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Väärä versio IP-osoitteesta"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Väärä aliverkonpeite."
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Käsitellään..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr "Kaikki saatavilla"
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr "Käyttäjät"
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr "Ei mitään saatavilla."
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr "Ei käyttäjiä"
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Tallenna"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s tehtiin onnistuneesti."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s ei valmistunut."
diff --git a/horizon/locale/fr/LC_MESSAGES/django.mo b/horizon/locale/fr/LC_MESSAGES/django.mo
deleted file mode 100644
index 3afade6f..00000000
--- a/horizon/locale/fr/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/fr/LC_MESSAGES/django.po b/horizon/locale/fr/LC_MESSAGES/django.po
deleted file mode 100644
index d180f4e2..00000000
--- a/horizon/locale/fr/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,510 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2012-05-08 20:22+0000\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: fr\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr ""
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr ""
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr ""
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr ""
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr ""
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr ""
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr ""
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr ""
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr ""
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr ""
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr ""
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr ""
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr ""
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr ""
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr ""
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr ""
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr ""
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr ""
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr ""
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr ""
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr ""
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr ""
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr ""
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr ""
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr ""
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr ""
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr ""
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr ""
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr ""
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr ""
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr ""
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr ""
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr ""
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr ""
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr ""
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr ""
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr ""
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr ""
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr ""
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr ""
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr ""
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr ""
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr ""
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr ""
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr ""
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr ""
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr ""
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr ""
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr ""
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr ""
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr ""
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr ""
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr ""
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr ""
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr ""
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr ""
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr ""
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr ""
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr ""
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr ""
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr ""
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr ""
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr ""
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr ""
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr ""
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr ""
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr ""
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr ""
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr ""
diff --git a/horizon/locale/fr/LC_MESSAGES/djangojs.mo b/horizon/locale/fr/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index d0afa72c..00000000
--- a/horizon/locale/fr/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/fr/LC_MESSAGES/djangojs.po b/horizon/locale/fr/LC_MESSAGES/djangojs.po
deleted file mode 100644
index 559b85f2..00000000
--- a/horizon/locale/fr/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,74 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n > 1)\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/hu/LC_MESSAGES/django.mo b/horizon/locale/hu/LC_MESSAGES/django.mo
deleted file mode 100644
index 92a2fec0..00000000
--- a/horizon/locale/hu/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/hu/LC_MESSAGES/django.po b/horizon/locale/hu/LC_MESSAGES/django.po
deleted file mode 100644
index c19b0141..00000000
--- a/horizon/locale/hu/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,515 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2012
-# kelemeng <kelemeng@gnome.hu>, 2013
-# marton.kiss <marton.kiss@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: hu\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Egyéb"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Lépjen be a folytatáshoz."
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "Nincsen engedélyezve a hozzáférés ehhez: %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Jogosulatlan hozzáférés. Próbáljon meg belépni újra."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr "Navigációs elem"
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr "A böngészéshez válasszon egy %s elemet"
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "A jelszó nincs elfogadva"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Szűrő"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr "%(action)s %(data_type)s"
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr "---"
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "Nincsen hozzáférése ehhez: %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "Nem hajtható végre: %(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Törlés"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Törölve"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "A(z) %(attr)s attribútum nem létezik ezen: %(obj)s."
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "Nincs megjeleníthető elem."
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Műveletek"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "Nincs találat a(z) „%s” azonosítóhoz."
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Válasszon ki egy sort a művelet végrehajtása előtt."
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Belépve mint"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "Súgó"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "Kijelentkezés"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "Bejelentkezés"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "Bejelentkezés"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr "Nincs jogosultsága elérni:"
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr "Jelentkezzen be másik felhasználóként, vagy lépjen vissza a"
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr "kezdőlapra"
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "Bejelentkezés"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Információ: "
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Figyelmeztetés: "
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Siker: "
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Hiba: "
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "Összegzés"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "%(counter)s tétel megjelenítése"
-msgstr[1] "%(counter)s tétel megjelenítése"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr "Több"
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "Kvóta összefoglaló"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "Használt"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr "/"
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr "Elérhető példányok"
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "Elérhető vCPU-k"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "Szabad memória"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr "Elérhető kötetek"
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr "Elérhető tárhely"
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] "%(nav_items)s tétel megjelenítése"
-msgstr[1] "%(nav_items)s tétel megjelenítése"
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] "%(content_items)s tétel megjelenítése"
-msgstr[1] "%(content_items)s tétel megjelenítése"
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "Jelenlegi projekt"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "Válasszon egy hónapot a felhasználási adatok lekéréséhez"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "Beküldés"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Aktív példányok"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr "Aktív memória"
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "Havi vCPU-óra felhasználás"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "Havi GB-óra felhasználás"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Mégse"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "Horizon"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "Nincs korlát"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Elérhető"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d bájt"
-msgstr[1] "%(size)d bájt"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-msgstr[1] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "A jelszónak 8 és 18 karakter közöttinek kell lennie."
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "Cuki macskák"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "Morcos macskák"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Macskák"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Kismacskák"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Tigrisek"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Kutyák"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Kutyakölykök"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "Vezérlőpult"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "Panel"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Adminisztrációs panel"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "Óriás hangyák támadják San Francisco-t!"
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr "Biztonságban vagyunk a hangyáktól! Lépjen <a>ide</a>!"
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "Kötegelt"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "Kötegelt"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "Tétel"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "Tételek"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "Le"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "Fel"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "Csökkentve"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "Növelve"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr "Nincs műveletek táblázat"
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr "Egy tábla"
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "Első fül"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "Késleltetett fül"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "Letiltott fül"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "Nem engedélyezett fül"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "Saját táblázatom füle"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "Helyreállítható hiba fül"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Projekt"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "Felhasználó"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Első teszt művelet"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Példány"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Második teszt művelet"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Harmadik teszt művelet"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Adminisztrátor"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Adminisztrátori művelet"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Helytelen IP-cím formátum"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Érvénytelen IP-cím változat"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Érvénytelen alhálózati maszk"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Feldolgozás…"
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr "Összes elérhető"
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr "Tagok"
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr "Nincs elérhető."
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr "Nincsenek tagok."
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Mentés"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s sikeresen befejeződött."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s nem fejeződött be."
diff --git a/horizon/locale/it/LC_MESSAGES/django.mo b/horizon/locale/it/LC_MESSAGES/django.mo
deleted file mode 100644
index 95033772..00000000
--- a/horizon/locale/it/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/it/LC_MESSAGES/django.po b/horizon/locale/it/LC_MESSAGES/django.po
deleted file mode 100644
index f33dcf3b..00000000
--- a/horizon/locale/it/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,515 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Loris Strozzini <lstrozzini@gmail.com>, 2012
-# Salvatore Orlando <sorlando@nicira.com>, 2012
-# Stefano Maffulli <smaffulli@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: it\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Altro"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Accedi per continuare"
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "Accesso non autorizzato a %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Non autorizzato. Ritentare il login."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr ""
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "La password non è stata accettata."
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Filtro"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr ""
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr ""
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "Non si dispone dei permessi per %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Elimina"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Eliminato"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "L'attributo %(attr)s non esiste in %(obj)s"
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "Nessun elemento da visualizzare"
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Azioni"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "Nessuna corrispondenza restituita per l'identificativo \"%s\""
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Per cortesia, selezionare una riga prima di eseguire tale azione."
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr ""
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr ""
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr ""
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr ""
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr ""
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr ""
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Attenzione:"
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Successo:"
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Errore:"
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "Riepilogo"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "Progetto corrente"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Istanze attive"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr ""
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Annulla"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr ""
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr ""
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr ""
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr ""
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr ""
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr ""
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr ""
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr ""
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "Gattini carini"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "Gattacci feroci"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Gatti"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Micini"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Tigri"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Cani"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Cucciolini"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr ""
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr ""
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr ""
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "Scarrafoni giganti stanno attaccando Napoli!"
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr ""
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr ""
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr ""
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr ""
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr ""
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr ""
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr ""
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr ""
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr ""
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr ""
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr ""
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Progetto"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "Utente"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr ""
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Istanza"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr ""
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr ""
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Amministratore"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr ""
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Formato incorretto per l'indirizzo IP"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Versione dell'indirizzo IP non valida"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Maschera sottorete non valida."
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Attendere prego..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Salva"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s completato correttamente."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s non completato."
diff --git a/horizon/locale/it/LC_MESSAGES/djangojs.mo b/horizon/locale/it/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 2805f377..00000000
--- a/horizon/locale/it/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/it/LC_MESSAGES/djangojs.po b/horizon/locale/it/LC_MESSAGES/djangojs.po
deleted file mode 100644
index bceb2658..00000000
--- a/horizon/locale/it/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,74 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/ja/LC_MESSAGES/django.mo b/horizon/locale/ja/LC_MESSAGES/django.mo
deleted file mode 100644
index a919bcde..00000000
--- a/horizon/locale/ja/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/ja/LC_MESSAGES/django.po b/horizon/locale/ja/LC_MESSAGES/django.po
deleted file mode 100644
index 28c073fb..00000000
--- a/horizon/locale/ja/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,511 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Akihiro MOTOKI <amotoki@gmail.com>, 2013
-# bi.yamagata <bi.yamagata@gmail.com>, 2012
-# bi.yamagata <bi.yamagata@gmail.com>, 2012
-# Tomoyuki KATO <tomo@dream.daynight.jp>, 2012-2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-05-07 10:24+0000\n"
-"Last-Translator: Akihiro MOTOKI <amotoki@gmail.com>\n"
-"Language-Team: Japanese (http://www.transifex.com/projects/p/openstack/language/ja/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ja\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "その他"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "続行するには、ログインしてください。"
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "%s へのアクセスが許可されていません。"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "認証されていません。もう一度ログインしてください。"
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr "ナビゲーション項目"
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr "表示する %s を選択してください。"
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "パスワードを受け付けられません"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "フィルター"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr "%(data_type)sの%(action)s"
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr "N/A"
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "%(action)s を実行する権限がありません: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "%(action)s を実行できません: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "削除"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "削除しました"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "%(obj)s に 属性 %(attr)s が存在しません。"
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "表示する項目がありません。"
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "アクション"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "ID \"%s\" に一致するものがありません。"
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "このアクションを実行する前に、対象を選択してください。"
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "次の役割でログイン中"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "ヘルプ"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "ログアウト"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "ログイン"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "ログイン"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr "アクセスする権限がありません: "
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr "他のユーザーとしてログインしてください。または、戻ってください。"
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr "ホームページ"
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "ログイン"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "情報: "
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "警告: "
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "成功: "
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "エラー: "
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "概要"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "%(counter)s 項目の表示中"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr "さらに"
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "クォータ概要"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "使用済み"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr "/"
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr "利用可能なインスタンス"
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "利用可能な仮想 CPU"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "利用可能なメモリー"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr "利用可能なボリューム"
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr "利用可能なボリュームストレージ"
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] "%(nav_items)s 項目の表示中"
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] "%(content_items)s 項目の表示中"
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "現在のプロジェクト"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "使用量を問い合わせる月の選択"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "送信"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "稼働中のインスタンス"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr "使用中のメモリー"
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "今月の仮想 CPU 時間"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "今月の GB 時間"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "取り消し"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "Horizon"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "制限なし"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "利用可能"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d バイト"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "パスワードは 8 文字から 18 文字である必要があります。"
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "かわいいネコ"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "獰猛なネコ"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "ネコ"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "子ネコ"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "トラ"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "イヌ"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "子イヌ"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "マイダッシュボード"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "マイパネル"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "管理パネル"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "巨大な蟻がサンフランシスコを攻撃しています!"
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr "私たちは蟻から守られています ! <a>こちらへ</a> !"
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "バッチ"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "バッチを実行しました"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "項目"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "項目"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "下へ"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "上へ"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "下げました"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "上げました"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr "アクション表がありません"
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr "単一テーブル"
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "タブ 1"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "遅延されたタブ"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "無効化されたタブ"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "禁止されたタブ"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "テーブルのあるタブ"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "修復可能なエラーのタブ"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "プロジェクト"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "ユーザー"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "テストアクション 1"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "インスタンス"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "テストアクション 2"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "テストアクション 3"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "管理"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "管理アクション"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "不正な形式の IP アドレス"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "無効な IP アドレスのバージョン"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "無効なサブネットマスク"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "処理中..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr "利用可能な全項目"
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr "メンバー"
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr "利用可能な項目がありません。"
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr "メンバーがいません。"
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "保存"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s が正常に完了しました。"
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s が完了しませんでした。"
diff --git a/horizon/locale/ja/LC_MESSAGES/djangojs.mo b/horizon/locale/ja/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 18261fd6..00000000
--- a/horizon/locale/ja/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/ja/LC_MESSAGES/djangojs.po b/horizon/locale/ja/LC_MESSAGES/djangojs.po
deleted file mode 100644
index 8cf0876c..00000000
--- a/horizon/locale/ja/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,73 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=1; plural=0\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/ka_GE/LC_MESSAGES/django.mo b/horizon/locale/ka_GE/LC_MESSAGES/django.mo
deleted file mode 100644
index 7acad371..00000000
--- a/horizon/locale/ka_GE/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/ka_GE/LC_MESSAGES/django.po b/horizon/locale/ka_GE/LC_MESSAGES/django.po
deleted file mode 100644
index dd7b723a..00000000
--- a/horizon/locale/ka_GE/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,508 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Nika Chkhikvishvili <frrrredo@gmail.com>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ka_GE\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "სხვა"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr ""
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr ""
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr ""
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr ""
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr ""
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "ფილტრი"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr ""
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr ""
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "წაშლა"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "წაშლილი"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr ""
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr ""
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "მოქმედებები"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr ""
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "დახმარება"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "გამისვლა"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "შესვლა"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr ""
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr "მთავარი გვერდი"
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr ""
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr ""
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "გაფრთხილება:"
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "წარმატება:"
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr ""
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "ჯამი"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] ""
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr "მეტი"
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "კვოტის ჯამი"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "გამოყენებული"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "ხელმისაწვდომი RAM"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr "აქტიური RAM"
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr ""
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr ""
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr ""
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr ""
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr ""
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] ""
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] ""
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr ""
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr ""
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr ""
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr ""
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr ""
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr ""
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr ""
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr ""
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr ""
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr ""
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "ჩემი პანელი"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "ადმინ პანელი"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr ""
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr ""
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr ""
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr ""
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr ""
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "ქვევით"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "ზევით"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr ""
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr ""
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr ""
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr ""
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr ""
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr ""
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "პროექტი"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "მომხმარებელი"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr ""
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr ""
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr ""
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr ""
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr ""
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr ""
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr ""
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr ""
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr ""
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr ""
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr "წევრები"
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr "არ არაის წევრები."
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "შენახვა"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr ""
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr ""
diff --git a/horizon/locale/ko_KR/LC_MESSAGES/django.mo b/horizon/locale/ko_KR/LC_MESSAGES/django.mo
deleted file mode 100644
index 99425589..00000000
--- a/horizon/locale/ko_KR/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/ko_KR/LC_MESSAGES/django.po b/horizon/locale/ko_KR/LC_MESSAGES/django.po
deleted file mode 100644
index d5a1f75b..00000000
--- a/horizon/locale/ko_KR/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,509 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# bluejay.kr <bluejay.ahn@gmail.com>, 2012
-# Sungjin Gang <potopro@gmail.com>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-05-03 12:23+0000\n"
-"Last-Translator: Sungjin Gang <potopro@gmail.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ko_KR\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "다른"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "로그인을 해주세요."
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "%s에 접근 권한이 없습니다. "
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "인증되지 않았습니다. 다시 로깅해주시기 바랍니다. "
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr ""
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr ""
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "필터"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr ""
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr ""
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "%(action)s에 관한 권한이 없습니다.: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "%(action)s를 사용할 수 없습니다.: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "삭제"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "삭제했음"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr ""
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "표시할 항목이 없습니다."
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "작동"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "일치하는 id \"%s\"를 반환"
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr ""
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr ""
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr ""
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr ""
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr ""
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "정보:"
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "주의:"
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "완료:"
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "에러:"
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr ""
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "%(counter)s 항목 표시"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "제출"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "작동중인 인스턴스"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "한달간 VCPU-시간"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "한달간 GB-시간"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "취소"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr ""
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "유한한"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "사용가능한"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d bytes"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr ""
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr ""
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr ""
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr ""
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "내 대시보드"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "내 판넬"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "관리자 판넬"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr ""
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "일괄 처리"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "일괄 처리된"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "항목"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "항목들"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr ""
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr ""
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr ""
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr ""
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr ""
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr ""
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr ""
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "프로젝트"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "사용자"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr ""
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "인스턴스"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr ""
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr ""
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "관리자"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "관리자 액션"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr ""
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr ""
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr ""
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr ""
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "저장"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr ""
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr ""
diff --git a/horizon/locale/ko_KR/LC_MESSAGES/djangojs.mo b/horizon/locale/ko_KR/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 7ba1b294..00000000
--- a/horizon/locale/ko_KR/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/ko_KR/LC_MESSAGES/djangojs.po b/horizon/locale/ko_KR/LC_MESSAGES/djangojs.po
deleted file mode 100644
index c92986c1..00000000
--- a/horizon/locale/ko_KR/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,73 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/nl_NL/LC_MESSAGES/django.mo b/horizon/locale/nl_NL/LC_MESSAGES/django.mo
deleted file mode 100644
index da6ee644..00000000
--- a/horizon/locale/nl_NL/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/nl_NL/LC_MESSAGES/django.po b/horizon/locale/nl_NL/LC_MESSAGES/django.po
deleted file mode 100644
index 74c2f86f..00000000
--- a/horizon/locale/nl_NL/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,514 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Erik-Martijn Kasimier <erik.kasimier@nouveaumedia.nl>, 2012
-# Erik-Martijn Kasimier <erik.kasimier@nouveaumedia.nl>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: nl_NL\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Andere"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Log in om door te gaan."
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "Je bent niet geauthoriseerd om %s te bekijken"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Je bent niet geautoriseerd. Probeer opnieuw in te loggen."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr ""
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "Wachtwoord is niet geaccepteerd"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Filter"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr ""
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr ""
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Verwijder"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Verwijderd"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr ""
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr ""
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Acties"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr ""
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr ""
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr ""
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr ""
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr ""
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr ""
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Informatie: "
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Waarschuwing: "
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Succesvol: "
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Error: "
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr ""
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr ""
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Annuleren"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr ""
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "Geen limiet"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Beschikbaar"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d byte"
-msgstr[1] "%(size)d bytes"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-msgstr[1] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "Schattige katten"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "Felle katten"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Katten"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Kittens"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Tijgers"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Honden"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Puppy's"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "Mijn dashboard"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "Alle instances"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Beheerderspaneel"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr ""
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr ""
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr ""
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "Item"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "Items"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr ""
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr ""
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr ""
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr ""
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr ""
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr ""
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr ""
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Project"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "Gebruiker"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Testactie één"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Instance"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Testactie twee"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Testactie drie"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Beheerder"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Beheerdersactie"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Onjuist formaat IP adres"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Invalide versie IP adres"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Invalide subnet mask"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Verwerken..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Opslaan"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s succesvol afgerond."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s was niet voltooid."
diff --git a/horizon/locale/nl_NL/LC_MESSAGES/djangojs.mo b/horizon/locale/nl_NL/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 7ba1b294..00000000
--- a/horizon/locale/nl_NL/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/nl_NL/LC_MESSAGES/djangojs.po b/horizon/locale/nl_NL/LC_MESSAGES/djangojs.po
deleted file mode 100644
index c92986c1..00000000
--- a/horizon/locale/nl_NL/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,73 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/pl/LC_MESSAGES/django.mo b/horizon/locale/pl/LC_MESSAGES/django.mo
deleted file mode 100644
index d8192fe0..00000000
--- a/horizon/locale/pl/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/pl/LC_MESSAGES/django.po b/horizon/locale/pl/LC_MESSAGES/django.po
deleted file mode 100644
index 99b2e8c4..00000000
--- a/horizon/locale/pl/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,530 +0,0 @@
-# Translations of the Horizon Dashboard project.
-# Copyright 2011 Midokura KK
-# This file is distributed under the same license as the Horizon package.
-# FIRST AUTHOR Jeffrey Wilcox, 2011.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openstack-dashboard\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2011-09-24 14:41+0100\n"
-"Last-Translator: Tomasz 'Zen' Napierala <tomasz@napierala.org>\n"
-"Language-Team: Polish OpenStack translations team <tomasz+openstack-"
-"i18n@napierala.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Language: Polish\n"
-"X-Poedit-Country: POLAND\n"
-"X-Poedit-SourceCharset: utf-8\n"
-
-#: base.py:424
-msgid "Other"
-msgstr ""
-
-#: decorators.py:55
-#, fuzzy
-msgid "Please log in to continue."
-msgstr "Nie można usunąć klucza: %s"
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr ""
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr ""
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, fuzzy, python-format
-msgid "Select a %s to browse."
-msgstr "Usuń projekt"
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr ""
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr ""
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr ""
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr ""
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:595
-#, fuzzy, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "Nie można usunąć klucza: %s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Usuń"
-
-#: tables/actions.py:612
-#, fuzzy
-msgid "Deleted"
-msgstr "Usuń"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr ""
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr ""
-
-#: tables/base.py:852
-#, fuzzy
-msgid "Actions"
-msgstr "Położenie"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr ""
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr ""
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr ""
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr ""
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr ""
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr ""
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr ""
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr ""
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr ""
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr ""
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr ""
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#, fuzzy
-msgid "Available Instances"
-msgstr "Instancje"
-
-#: templates/horizon/common/_quota_summary.html:8
-#, fuzzy
-msgid "Available vCPUs"
-msgstr "brak dostępnych"
-
-#: templates/horizon/common/_quota_summary.html:11
-#, fuzzy
-msgid "Available RAM"
-msgstr "brak dostępnych"
-
-#: templates/horizon/common/_quota_summary.html:15
-#, fuzzy
-msgid "Available volumes"
-msgstr "brak dostępnych"
-
-#: templates/horizon/common/_quota_summary.html:18
-#, fuzzy
-msgid "Available volume storage"
-msgstr "Instancje"
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_sidebar.html:14
-#, fuzzy
-msgid "Current Project"
-msgstr "Usuń projekt"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:14
-#, fuzzy
-msgid "Active Instances"
-msgstr "Zobacz instancje"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr ""
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr ""
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr ""
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr ""
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-#, fuzzy
-msgid "Available"
-msgstr "brak dostępnych"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr ""
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr ""
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr ""
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr ""
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr ""
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr ""
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr ""
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr ""
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr ""
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr ""
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr ""
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr ""
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr ""
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr ""
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr ""
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr ""
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr ""
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr ""
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr ""
-
-#: test/tests/tables.py:187
-#, fuzzy
-msgid "No Actions Table"
-msgstr "Położenie"
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr ""
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr ""
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr ""
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr ""
-
-#: test/tests/workflows.py:43
-#, fuzzy
-msgid "Project"
-msgstr "Usuń projekt"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr ""
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr ""
-
-#: test/tests/workflows.py:61
-#, fuzzy
-msgid "Instance"
-msgstr "Instancje"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr ""
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr ""
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr ""
-
-#: test/tests/workflows.py:80
-#, fuzzy
-msgid "Admin Action"
-msgstr "Położenie"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr ""
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr ""
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr ""
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr ""
-
-#: workflows/base.py:467
-#, fuzzy
-msgid "All available"
-msgstr "brak dostępnych"
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-#, fuzzy
-msgid "None available."
-msgstr "brak dostępnych"
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr ""
-
-#: workflows/base.py:570
-#, fuzzy, python-format
-msgid "%s completed successfully."
-msgstr "Wolumen %(id)s %(name)s został pomyślnie utworzony."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr ""
diff --git a/horizon/locale/pl/LC_MESSAGES/djangojs.mo b/horizon/locale/pl/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 97de9ec8..00000000
--- a/horizon/locale/pl/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/pl/LC_MESSAGES/djangojs.po b/horizon/locale/pl/LC_MESSAGES/djangojs.po
deleted file mode 100644
index 1e1e4fe9..00000000
--- a/horizon/locale/pl/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,76 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
-"|| n%100>=20) ? 1 : 2)\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/pt/LC_MESSAGES/django.mo b/horizon/locale/pt/LC_MESSAGES/django.mo
deleted file mode 100644
index 253a3596..00000000
--- a/horizon/locale/pt/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/pt/LC_MESSAGES/django.po b/horizon/locale/pt/LC_MESSAGES/django.po
deleted file mode 100644
index b1d64fd2..00000000
--- a/horizon/locale/pt/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,513 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# FIRST AUTHOR Jeffrey Wilcox, 2011
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: pt\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Outro"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Por favor login para continuar"
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "Voçê não pode acessar %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Não autorizado. Por favor, tente efetuar login novamente."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr ""
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "Senha não é aceita"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Filtro"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr ""
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr ""
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "Você não tem permissão para %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "Incapaz de %(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr ""
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Excluir"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Excluído"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "O %(attr)s atributo não existe em %(obj)s."
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "Não há itens para mostrar."
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Ações"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "No jogo voltou para a ID de \"%s\"."
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Por favor, selecione uma linha antes de tomar essa ação."
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr ""
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr ""
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr ""
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr ""
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr ""
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Informações: "
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Aviso: "
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Sucesso: "
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Erro: "
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr ""
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "Selecione um mês para consultar o seu uso"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "Enviar"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Instâncias Ativas"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "VCPU-Horas deste mês"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "GB-Horas deste mês"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr ""
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "Nenhum Limite"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Disponível"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] ""
-msgstr[1] ""
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "A senha deve ter entre 8 e 18 caracteres."
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "Coatis Bonitos"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "Maluco Coatis"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Coatis"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Coatinhos"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Capybaras"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Macacas"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Macacas"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "Meu Dashboard"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "Meu Painel"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Painel de Administração"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr ""
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "Agrupar"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "Agrupadas"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "Item"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "Itens"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "Desativar"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "Elevar"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "Desativado"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "Elevado"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr ""
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "Guia Um"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "Guia Atraso"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "Desativado Guia"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "Guia não permitido"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "Guia à minha mesa"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "Guia de Erro Recuperável"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Projeto"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "Usuário"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Ação Teste dos Um"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Instância"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Ação Teste dos Dois"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Ação Teste dos Três"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Administração"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Ação de Administração"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Formato incorreto para o endereço IP"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Inválido versão para o endereço IP"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Máscara de sub-rede inválida"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Processamento..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Guardar"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s concluída com êxito."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s não foi concluída."
diff --git a/horizon/locale/pt/LC_MESSAGES/djangojs.mo b/horizon/locale/pt/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 20d4a6dc..00000000
--- a/horizon/locale/pt/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/pt/LC_MESSAGES/djangojs.po b/horizon/locale/pt/LC_MESSAGES/djangojs.po
deleted file mode 100644
index 03ebd97c..00000000
--- a/horizon/locale/pt/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,74 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/pt_BR/LC_MESSAGES/django.mo b/horizon/locale/pt_BR/LC_MESSAGES/django.mo
deleted file mode 100644
index f54133cc..00000000
--- a/horizon/locale/pt_BR/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/pt_BR/LC_MESSAGES/django.po b/horizon/locale/pt_BR/LC_MESSAGES/django.po
deleted file mode 100644
index 402da8b0..00000000
--- a/horizon/locale/pt_BR/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,518 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Josemar Müller Lohn <j@lo.hn>, 2013
-# Leonardo Rodrigues de Mello <leonardo@gridstack.com.br>, 2012
-# Leonardo Rodrigues de Mello <leonardo@gridstack.com.br>, 2012
-# Marcelo Dieder <marcelodieder@gmail.com>, 2012
-# openfly <matt@nycresistor.com>, 2012
-# Welkson Renny de Medeiros <welkson@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: pt_BR\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "Outro"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Por favor faça login para continuar."
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "Você está autorizado a acessar %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Não autorizado. Por favor, tente efetuar login novamente."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr "Item de Navegação"
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr "Selecione um %s para navegar."
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "senha não foi aceita"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Filtro"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr "%(action)s %(data_type)s"
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr "N/D"
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "Você não tem permissão para %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "Não foi possível %(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Remover"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Removido"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "O Atributo %(attr)s não existem em %(obj)s."
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "Não existem items para mostrar."
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Ações"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "Não foi encontrada correspondência para a id \"%s\"."
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Por favor selecione uma célula antes de realizar esta ação"
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Logado como:"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "Ajuda"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "Sair"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "Logar"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "Entrar"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr "Você não tem permissão para acessar:"
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr "Logue como um usuário diferente ou volte"
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr "página principal"
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "Registrar"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Informação:"
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Alerta:"
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Sucesso:"
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Erro:"
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "Resumo"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "Mostrando %(counter)s item"
-msgstr[1] "Mostrando %(counter)s items"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr "Mais"
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "Resumo de Quota"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "Usado"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr "de"
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr "Instâncias disponíveis"
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "vCPUs disponíveis"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "RAM disponível"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr "Volumes disponíveis"
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr "Volume de armazenamento disponível"
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] "Mostrando %(nav_items)s item"
-msgstr[1] "Mostrando %(nav_items)s items"
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] "Mostrando %(content_items)s item"
-msgstr[1] "Mostrando %(content_items)s items"
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "projeto atual"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "Escolha um mês para consultar sua utilização"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "Enviar"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Instâncias ativas"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr "RAM ativa"
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "VCPU-Horas este mês"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "GB-Horas este mês"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "Horizon"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "Sem limite"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Disponível"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d byte"
-msgstr[1] "%(size)d bytes"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-msgstr[1] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s TB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "As senhas devem ter entre 8 e 18 caracteres."
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "quatis beleza"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "quatis maluco"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "quatis"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "bebê quati"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Capybaras"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Macacas"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Macacos pequenos"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "Meu Dashboard"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "Meu Painel"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Painel Administrativo"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "Formigas gigantes estão atacando São Paulo!"
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr "Agora estamos salvos das formigas! Vá <a>aqui</a>!"
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "Lote"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "Lote"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "Item"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "Itens"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "Para baixo"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "Para cima"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "Baixado"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "Levantado"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr "Tabela Sem Ação"
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr "Tabela simples"
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "Aba Um"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "Aba Atrasada"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "Aba Desativada"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "Aba Proibida"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "Aba Com Minha Tabela"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "Aba de Erros Recuperáveis"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Projeto"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "Usuário"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Testando Ação Um"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Instância"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Testando Ação Dois"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Testando Ação Três"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Administrador"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Ação de Administrador"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Endereço IP no formato incorreto"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Versão inválida para o endereço IP"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Máscara de rede inválida"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Processando..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr "Tudo disponível"
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr "Membros"
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr "Nenhum disponível."
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr "Sem membros."
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Salvar"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s concluído com sucesso."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s não completou."
diff --git a/horizon/locale/pt_BR/LC_MESSAGES/djangojs.mo b/horizon/locale/pt_BR/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index d0afa72c..00000000
--- a/horizon/locale/pt_BR/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/pt_BR/LC_MESSAGES/djangojs.po b/horizon/locale/pt_BR/LC_MESSAGES/djangojs.po
deleted file mode 100644
index 559b85f2..00000000
--- a/horizon/locale/pt_BR/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,74 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n > 1)\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/ru/LC_MESSAGES/django.mo b/horizon/locale/ru/LC_MESSAGES/django.mo
deleted file mode 100644
index aa57765c..00000000
--- a/horizon/locale/ru/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/ru/LC_MESSAGES/django.po b/horizon/locale/ru/LC_MESSAGES/django.po
deleted file mode 100644
index d8c9792c..00000000
--- a/horizon/locale/ru/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,520 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# adiantum <ilyaalekseyev@acm.org>, 2012
-# Stanislav Hanzhin <hanzhin.stas@gmail.com>, 2012
-# lykoz <woof@stopme.net>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ru\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"
-
-#: base.py:424
-msgid "Other"
-msgstr "Другое"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "Чтобы продолжить, необходимо выполнить вход."
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "Доступ к %s не авторизован"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "Нет авторизации. Попробуйте выполнить вход повторно."
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr "Элемент навигации"
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr "Выберите %s для просмотра"
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "Пароль не принят"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "Фильтр"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr "%(action)s %(data_type)s"
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr "Н/Д"
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "У вас нет прав на выполнение %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "Невозможно выполнить %(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "Удалить"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "Удалено"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "Атрибут %(attr)s не существует для %(obj)s."
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "Нет элементов для отображения."
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "Действия"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "Не найдено соответствий для id \"%s\"."
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "Выберите строку перед выполнением действия."
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Вы вошли как"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "Помощь"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "Выйти"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "Имя пользователя"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "Войти"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr ""
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "Зарегистрироваться"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "Инфо:"
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "Внимание:"
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "Успешно:"
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "Ошибка:"
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "Итого"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "Отображаем %(counter)s элемент"
-msgstr[1] "Отображаем %(counter)s элемента"
-msgstr[2] "Отображаем %(counter)s элементов"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "Итого"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "Использовано"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr "из"
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr "Все экземпляры"
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "Доступно"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "Доступно"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] "Отображение %(nav_items)s элемента"
-msgstr[1] "Отображение %(nav_items)s элементов"
-msgstr[2] "Отображение %(nav_items)s элементов"
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] "Отображение %(content_items)s элемента"
-msgstr[1] "Отображение %(content_items)s элементов"
-msgstr[2] "Отображение %(content_items)s элементов"
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "Текущий проект"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "Выберите месяц для анализа потребления ресурсов"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "Отправить"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "Активные экземпляры"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr "Активная память"
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "VCPU-Часов в этом месяце"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "ГБ-Часов в этом месяце"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "Отмена"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "Horizon"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "Нет ограничения"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "Доступно"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d байт"
-msgstr[1] "%(size)d байта"
-msgstr[2] "%(size)d байт"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-msgstr[1] "%(size)d"
-msgstr[2] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s КБ"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s МБ"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s ГБ"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s ТБ"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s ПБ"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "Пароль должен иметь длину от 8 до 18 символов."
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "Милые кошки"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "Свирепые кошки"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Кошки"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Котята"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Тигры"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Собаки"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Щенки"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "Моя панель управления"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "Моя панель"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "Панель администратора"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "Гигантские муравьи атакуют Сан-Франциско"
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "Пакет"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "Пакетом"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "Элемент"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "Элементы"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "Остановлен"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "Запущен"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "Опущено"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "Поднято"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr "Нет таблиц действий"
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "Вкладка один"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "Вкладка с задержкой"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "Отключенная вкладка"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "Запрещённая вкладка"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "Вкладка с моей таблицей"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "Владка с восстановимой ошибкой"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "Проект"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "Пользователь"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Тестовое действие один"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "Экземпляр"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Тестовое действие два"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Тестовое действие три"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "Администратор"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Действие адмиистратора"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "Неправильный формат IP адреса"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "Неправильная версия для IP адреса"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "Неправльная маска подсети"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "Обработка…"
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "Сохранить"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s успешно завершено."
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s не завершено."
diff --git a/horizon/locale/ru/LC_MESSAGES/djangojs.mo b/horizon/locale/ru/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 82571bb9..00000000
--- a/horizon/locale/ru/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/ru/LC_MESSAGES/djangojs.po b/horizon/locale/ru/LC_MESSAGES/djangojs.po
deleted file mode 100644
index 9a5f3639..00000000
--- a/horizon/locale/ru/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,75 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\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"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-msgstr[1] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/zh_CN/LC_MESSAGES/django.mo b/horizon/locale/zh_CN/LC_MESSAGES/django.mo
deleted file mode 100644
index 6452264a..00000000
--- a/horizon/locale/zh_CN/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/zh_CN/LC_MESSAGES/django.po b/horizon/locale/zh_CN/LC_MESSAGES/django.po
deleted file mode 100644
index f73be594..00000000
--- a/horizon/locale/zh_CN/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,516 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# linlg <bbpp10@qq.com>, 2013
-# cateester <cateester@gmail.com>, 2012
-# daisy.ycguo <daisy.ycguo@gmail.com>, 2012
-# FIRST AUTHOR Jeffrey Wilcox, 2011
-# laurence.miao <laurence.miao@gmail.com>, 2012
-# dangdang <11315889@qq.com>, 2012
-# QunShi Zhang <zhang.kris@gmail.com>, 2012
-# dangdang <11315889@qq.com>, 2013
-# yuanke wei <weiyuanke123@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_CN\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "其他"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "请登录先。"
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "您无权访问 %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "未授权。请尝试重新登录。"
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr "选择一个%s 浏览"
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "密码没有接受"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "筛选"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr "%(action)s %(data_type)s"
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr "无"
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "您没有权限执行 %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "无法执行 %(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "删除"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "被删除"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "属性 %(attr)s 并不存在于 %(obj)s。"
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "没有条目显示。"
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "动作"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "id \"%s\" 没有匹配的返回顶"
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "请在执行前选择一行。"
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "当前用户"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "帮助"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "退出"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "登录"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "登录"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr "主页"
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "登入"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "信息:"
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "警告:"
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "成功:"
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "错误:"
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "概要"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "显示 %(counter)s 个条目"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr "配额摘要"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "已使用"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr " / "
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr "可用云主机"
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "可用VCPU"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "可用内存"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "当前项目"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "选择一个月份查询它的使用情况"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "提交"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "活跃的云主机"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "本月的 VCPU 小时时间"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "本月的 GB 小时时间"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "取消"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "控制面板"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "无限制"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "可用配额"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d 字节"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] ""
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "密码必须是8到18位的字符。"
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr "Cute Cats"
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr "Fierce Cats"
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr "Cats"
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr "Kittens"
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr "Tigers"
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr "Dogs"
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr "Puppies"
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "我的控制面板"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "我的控制面板"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "管理员面板"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr "巨大的蚂蚁们正在攻击旧金山。"
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "批"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "分批的"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "条目"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "条目"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "向下"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "向上"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "向下的"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "向上的"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr ""
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "Tab 1"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "推迟的Tab"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "禁用的Tab"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "不允许的Tab"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "我的表格中的Tab"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "恢复的错误Tab"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "项目"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "用户"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "Test Action One"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "云主机"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "Test Action Two"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "Test Action Three"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "管理员"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "Admin Action"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "不正确的IP地址格式"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "IP 地址版本无效"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "无效的子网掩码"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "正在处理中,请稍候。。。"
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "保存"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s 创建成功"
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s 没有完成"
diff --git a/horizon/locale/zh_CN/LC_MESSAGES/djangojs.mo b/horizon/locale/zh_CN/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 86131e66..00000000
--- a/horizon/locale/zh_CN/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/zh_CN/LC_MESSAGES/djangojs.po b/horizon/locale/zh_CN/LC_MESSAGES/djangojs.po
deleted file mode 100644
index 64d5a020..00000000
--- a/horizon/locale/zh_CN/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,73 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=1; plural=0\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/locale/zh_HK/LC_MESSAGES/django.mo b/horizon/locale/zh_HK/LC_MESSAGES/django.mo
deleted file mode 100644
index 15d701f7..00000000
--- a/horizon/locale/zh_HK/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/zh_HK/LC_MESSAGES/django.po b/horizon/locale/zh_HK/LC_MESSAGES/django.po
deleted file mode 100644
index a9675296..00000000
--- a/horizon/locale/zh_HK/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,508 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# MXKiN <mxkckin@gmail.com>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_HK\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "其他"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "請登入才可繼續。"
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "你沒有授權去存取 %s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "未經授權。請嘗試重新登入。"
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr ""
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr ""
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr ""
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "過濾"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr ""
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr ""
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "你沒有權限 %(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "無法 %(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s: %(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "刪除"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "已刪除"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "屬性 %(attr)s 不存在於 %(obj)s。"
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "沒有任何項目可以顯示。"
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "動作"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr ""
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "登入為"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "幫助"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "登出"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "登入"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "登入"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr "你沒有權限去存取:"
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr "登入為其他用戶或返回"
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr "主頁"
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr "登入"
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "信息: "
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "警告:"
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "成功:"
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "錯誤:"
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr ""
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] ""
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr "更多"
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr "已使用"
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr "可用的虛擬處理器"
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr "可用的記憶體"
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr "可用的卷冊"
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr "可用的卷冊儲存"
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] ""
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] ""
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "提交"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr "使用的記憶體"
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr ""
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "取消"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "Horizon"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "沒有任何限制"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "可用的"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d 位元組"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr ""
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr ""
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr ""
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr ""
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr ""
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr ""
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr ""
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr ""
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr "現在我們已經安全及遠離螞蟻的攻擊! 請去<a>這裡</a>!"
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "批次"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "已批次"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "項目"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "項目"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "調低"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "調高"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr "已調低"
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr "已調高"
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr ""
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr "單一表格"
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr ""
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr ""
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr ""
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr ""
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr ""
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "專案"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "用戶"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr ""
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr ""
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr ""
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr ""
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "管理"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr ""
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr ""
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr ""
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr ""
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "處理中..."
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr "全部可用"
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr "成員"
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr "無可用的。"
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr "沒有任何成員。"
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "儲存"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s已成功完成。"
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s未能完成。"
diff --git a/horizon/locale/zh_TW/LC_MESSAGES/django.mo b/horizon/locale/zh_TW/LC_MESSAGES/django.mo
deleted file mode 100644
index 540b0001..00000000
--- a/horizon/locale/zh_TW/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/zh_TW/LC_MESSAGES/django.po b/horizon/locale/zh_TW/LC_MESSAGES/django.po
deleted file mode 100644
index a2fbec42..00000000
--- a/horizon/locale/zh_TW/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,508 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Chao-Hsiung Liao <pesder@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:08+0000\n"
-"PO-Revision-Date: 2013-04-29 08:33+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/openstack/language/zh_TW/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_TW\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#: base.py:424
-msgid "Other"
-msgstr "其它"
-
-#: decorators.py:55
-msgid "Please log in to continue."
-msgstr "請登入以繼續。"
-
-#: decorators.py:87
-#, python-format
-msgid "You are not authorized to access %s"
-msgstr "您的權限不足 無法查看%s"
-
-#: exceptions.py:283
-msgid "Unauthorized. Please try logging in again."
-msgstr "權限不足。 請重新登入。"
-
-#: browsers/base.py:90
-msgid "Navigation Item"
-msgstr "導覽項目"
-
-#: browsers/views.py:42
-#, python-format
-msgid "Select a %s to browse."
-msgstr "選擇要瀏覽的 %s。"
-
-#: conf/default.py:29
-msgid "Password is not accepted"
-msgstr "密碼不被接受"
-
-#: tables/actions.py:349
-msgid "Filter"
-msgstr "搜尋"
-
-#: tables/actions.py:527
-#, python-format
-msgid "%(action)s %(data_type)s"
-msgstr "%(action)s %(data_type)s"
-
-#: tables/actions.py:561
-msgid "N/A"
-msgstr "N/A"
-
-#: tables/actions.py:589
-#, python-format
-msgid "You do not have permission to %(action)s: %(objs)s"
-msgstr "您沒有權限使用%(action)s: %(objs)s"
-
-#: tables/actions.py:595
-#, python-format
-msgid "Unable to %(action)s: %(objs)s"
-msgstr "無法%(action)s: %(objs)s"
-
-#: tables/actions.py:601
-#, python-format
-msgid "%(action)s: %(objs)s"
-msgstr "%(action)s:%(objs)s"
-
-#: tables/actions.py:611
-msgid "Delete"
-msgstr "刪除"
-
-#: tables/actions.py:612
-msgid "Deleted"
-msgstr "已刪除"
-
-#: tables/base.py:275
-#, python-format
-msgid "The attribute %(attr)s doesn't exist on %(obj)s."
-msgstr "此屬性%(attr)s並不在%(obj)s上存在。"
-
-#: tables/base.py:748
-msgid "No items to display."
-msgstr "沒有任何相關項目"
-
-#: tables/base.py:852
-msgid "Actions"
-msgstr "動作"
-
-#: tables/base.py:1035
-#, python-format
-msgid "No match returned for the id \"%s\"."
-msgstr "找不到id \"%s\"的相關項目"
-
-#: tables/base.py:1165
-msgid "Please select a row before taking that action."
-msgstr "請選擇一個欄位後才執行動作"
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "登入為"
-
-#: templates/_header.html:5
-msgid "Help"
-msgstr "求助"
-
-#: templates/_header.html:7
-msgid "Sign Out"
-msgstr "登出"
-
-#: templates/splash.html:7 templates/auth/login.html:4
-msgid "Login"
-msgstr "登入"
-
-#: templates/auth/_login.html:4
-msgid "Log In"
-msgstr "登入"
-
-#: templates/auth/_login.html:14
-msgid "You don't have permissions to access:"
-msgstr ""
-
-#: templates/auth/_login.html:16
-msgid "Login as different user or go back to"
-msgstr ""
-
-#: templates/auth/_login.html:17
-msgid "home page"
-msgstr ""
-
-#: templates/auth/_login.html:27
-msgid "Sign In"
-msgstr ""
-
-#: templates/horizon/_messages.html:7
-msgid "Info: "
-msgstr "資訊: "
-
-#: templates/horizon/_messages.html:13
-msgid "Warning: "
-msgstr "警告: "
-
-#: templates/horizon/_messages.html:19
-msgid "Success: "
-msgstr "成功: "
-
-#: templates/horizon/_messages.html:25
-msgid "Error: "
-msgstr "錯誤: "
-
-#: templates/horizon/common/_data_table.html:54
-msgid "Summary"
-msgstr "摘要"
-
-#: templates/horizon/common/_data_table.html:63
-#, python-format
-msgid "Displaying %(counter)s item"
-msgid_plural "Displaying %(counter)s items"
-msgstr[0] "顯示 %(counter)s 個項目"
-
-#: templates/horizon/common/_data_table_row_actions.html:10
-msgid "More"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:4
-msgid "Quota Summary"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Used"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-#: templates/horizon/common/_quota_summary.html:8
-#: templates/horizon/common/_quota_summary.html:11
-#: templates/horizon/common/_quota_summary.html:15
-#: templates/horizon/common/_quota_summary.html:18
-msgid "of"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:5
-msgid "Available Instances"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:8
-msgid "Available vCPUs"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:11
-msgid "Available RAM"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:15
-msgid "Available volumes"
-msgstr ""
-
-#: templates/horizon/common/_quota_summary.html:18
-msgid "Available volume storage"
-msgstr ""
-
-#: templates/horizon/common/_resource_browser.html:10
-#, python-format
-msgid "Displaying %(nav_items)s item"
-msgid_plural "Displaying %(nav_items)s items"
-msgstr[0] "顯示 %(nav_items)s 個項目"
-
-#: templates/horizon/common/_resource_browser.html:11
-#, python-format
-msgid "Displaying %(content_items)s item"
-msgid_plural "Displaying %(content_items)s items"
-msgstr[0] "顯示 %(content_items)s 個項目"
-
-#: templates/horizon/common/_sidebar.html:14
-msgid "Current Project"
-msgstr "目前的專案"
-
-#: templates/horizon/common/_usage_summary.html:5
-msgid "Select a month to query its usage"
-msgstr "請選擇一個月份以查詢使用量"
-
-#: templates/horizon/common/_usage_summary.html:9
-msgid "Submit"
-msgstr "提交"
-
-#: templates/horizon/common/_usage_summary.html:14
-msgid "Active Instances"
-msgstr "運作中執行個體"
-
-#: templates/horizon/common/_usage_summary.html:15
-msgid "Active RAM"
-msgstr ""
-
-#: templates/horizon/common/_usage_summary.html:16
-msgid "This Month's VCPU-Hours"
-msgstr "本月的虛擬處理器-時數"
-
-#: templates/horizon/common/_usage_summary.html:17
-msgid "This Month's GB-Hours"
-msgstr "本月的GB-時數"
-
-#: templates/horizon/common/_workflow.html:33
-msgid "Cancel"
-msgstr "取消"
-
-#: templatetags/branding.py:35
-msgid "Horizon"
-msgstr "Horizon"
-
-#: templatetags/horizon.py:109
-msgid "No Limit"
-msgstr "不限制"
-
-#: templatetags/horizon.py:111 templatetags/horizon.py:113
-msgid "Available"
-msgstr "可用"
-
-#: templatetags/sizeformat.py:45
-#, python-format
-msgid "%(size)d byte"
-msgid_plural "%(size)d bytes"
-msgstr[0] "%(size)d 位元組"
-
-#: templatetags/sizeformat.py:49
-#, python-format
-msgid "%(size)d"
-msgid_plural "%(size)d"
-msgstr[0] "%(size)d"
-
-#: templatetags/sizeformat.py:52
-#, python-format
-msgid "%s KB"
-msgstr "%s KB"
-
-#: templatetags/sizeformat.py:55
-#, python-format
-msgid "%s MB"
-msgstr "%s MB"
-
-#: templatetags/sizeformat.py:58
-#, python-format
-msgid "%s GB"
-msgstr "%s GB"
-
-#: templatetags/sizeformat.py:61
-#, python-format
-msgid "%s TB"
-msgstr "%s TB"
-
-#: templatetags/sizeformat.py:63
-#, python-format
-msgid "%s PB"
-msgstr "%s PB"
-
-#: test/settings.py:114
-msgid "Password must be between 8 and 18 characters."
-msgstr "密碼必須介於 8 到 18 個字元之間。"
-
-#: test/test_dashboards/cats/dashboard.py:8
-msgid "Cute Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:14
-msgid "Fierce Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/dashboard.py:19
-msgid "Cats"
-msgstr ""
-
-#: test/test_dashboards/cats/kittens/panel.py:9
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:3
-#: test/test_dashboards/cats/kittens/templates/kittens/index.html:6
-msgid "Kittens"
-msgstr ""
-
-#: test/test_dashboards/cats/tigers/panel.py:9
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:3
-#: test/test_dashboards/cats/tigers/templates/tigers/index.html:6
-msgid "Tigers"
-msgstr ""
-
-#: test/test_dashboards/dogs/dashboard.py:7
-msgid "Dogs"
-msgstr ""
-
-#: test/test_dashboards/dogs/puppies/panel.py:9
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:3
-#: test/test_dashboards/dogs/puppies/templates/puppies/index.html:6
-msgid "Puppies"
-msgstr ""
-
-#: test/tests/base.py:39
-msgid "My Dashboard"
-msgstr "我的 Dashboard"
-
-#: test/tests/base.py:45
-msgid "My Panel"
-msgstr "我的面板"
-
-#: test/tests/base.py:51
-msgid "Admin Panel"
-msgstr "管理面板"
-
-#: test/tests/messages.py:32
-msgid "Giant ants are attacking San Francisco!"
-msgstr ""
-
-#: test/tests/messages.py:46
-msgid "We are now safe from ants! Go <a>here</a>!"
-msgstr ""
-
-#: test/tests/tables.py:107
-msgid "Batch"
-msgstr "批次"
-
-#: test/tests/tables.py:108
-msgid "Batched"
-msgstr "已批次"
-
-#: test/tests/tables.py:109 test/tests/tables.py:120
-msgid "Item"
-msgstr "項目"
-
-#: test/tests/tables.py:110 test/tests/tables.py:121
-msgid "Items"
-msgstr "項目"
-
-#: test/tests/tables.py:118
-msgid "Down"
-msgstr "下"
-
-#: test/tests/tables.py:118
-msgid "Up"
-msgstr "上"
-
-#: test/tests/tables.py:119
-msgid "Downed"
-msgstr ""
-
-#: test/tests/tables.py:119
-msgid "Upped"
-msgstr ""
-
-#: test/tests/tables.py:187
-msgid "No Actions Table"
-msgstr "沒有動作表格"
-
-#: test/tests/tables.py:684
-msgid "Single Table"
-msgstr ""
-
-#: test/tests/tabs.py:36
-msgid "Tab One"
-msgstr "分頁一"
-
-#: test/tests/tabs.py:42
-msgid "Delayed Tab"
-msgstr "延遲分頁"
-
-#: test/tests/tabs.py:49
-msgid "Disabled Tab"
-msgstr "停用分頁"
-
-#: test/tests/tabs.py:58
-msgid "Disallowed Tab"
-msgstr "不允許分頁"
-
-#: test/tests/tabs.py:76
-msgid "Tab With My Table"
-msgstr "我的表格分頁"
-
-#: test/tests/tabs.py:85
-msgid "Recoverable Error Tab"
-msgstr "可回復錯誤分頁"
-
-#: test/tests/workflows.py:43
-msgid "Project"
-msgstr "專案"
-
-#: test/tests/workflows.py:44
-msgid "User"
-msgstr "使用者"
-
-#: test/tests/workflows.py:47
-msgid "Test Action One"
-msgstr "測試動作一"
-
-#: test/tests/workflows.py:61
-msgid "Instance"
-msgstr "執行個體"
-
-#: test/tests/workflows.py:64
-msgid "Test Action Two"
-msgstr "測試動作二"
-
-#: test/tests/workflows.py:72
-msgid "Test Action Three"
-msgstr "測試動作三"
-
-#: test/tests/workflows.py:77
-msgid "Admin"
-msgstr "管理者"
-
-#: test/tests/workflows.py:80
-msgid "Admin Action"
-msgstr "管理動作"
-
-#: utils/fields.py:46
-msgid "Incorrect format for IP address"
-msgstr "IP 位址格式不正確"
-
-#: utils/fields.py:47
-msgid "Invalid version for IP address"
-msgstr "IP 位址版本無效"
-
-#: utils/fields.py:48
-msgid "Invalid subnet mask"
-msgstr "無效的子網路遮罩"
-
-#: workflows/base.py:71
-msgid "Processing..."
-msgstr "處理中…"
-
-#: workflows/base.py:467
-msgid "All available"
-msgstr ""
-
-#: workflows/base.py:468
-msgid "Members"
-msgstr ""
-
-#: workflows/base.py:469
-msgid "None available."
-msgstr ""
-
-#: workflows/base.py:470
-msgid "No members."
-msgstr ""
-
-#: workflows/base.py:569
-msgid "Save"
-msgstr "儲存"
-
-#: workflows/base.py:570
-#, python-format
-msgid "%s completed successfully."
-msgstr "%s 已成功的完成。"
-
-#: workflows/base.py:571
-#, python-format
-msgid "%s did not complete."
-msgstr "%s 尚未完成。"
diff --git a/horizon/locale/zh_TW/LC_MESSAGES/djangojs.mo b/horizon/locale/zh_TW/LC_MESSAGES/djangojs.mo
deleted file mode 100644
index 18261fd6..00000000
--- a/horizon/locale/zh_TW/LC_MESSAGES/djangojs.mo
+++ /dev/null
Binary files differ
diff --git a/horizon/locale/zh_TW/LC_MESSAGES/djangojs.po b/horizon/locale/zh_TW/LC_MESSAGES/djangojs.po
deleted file mode 100644
index 8cf0876c..00000000
--- a/horizon/locale/zh_TW/LC_MESSAGES/djangojs.po
+++ /dev/null
@@ -1,73 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=1; plural=0\n"
-
-#: static/horizon/js/horizon.forms.js:47
-msgid "Additional information here..."
-msgstr ""
-
-#: static/horizon/js/horizon.forms.js:53
-msgid "Filter"
-msgstr ""
-
-#: static/horizon/js/horizon.instances.js:28
-msgid "There was a problem communicating with the server, please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:125
-msgid "There was an error submitting the form. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:159 static/horizon/js/horizon.tabs.js:9
-msgid "Loading"
-msgstr ""
-
-#: static/horizon/js/horizon.modals.js:178
-msgid "An error occurred. Please try again."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:47
-msgid "An error occurred while updating."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:145
-msgid "You have selected "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:158
-msgid "Confirm "
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:159
-msgid "Please confirm your selection. This action cannot be undone."
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:173
-msgid "Working"
-msgstr ""
-
-#: static/horizon/js/horizon.tables.js:216
-#, c-format
-msgid "Displaying %s item"
-msgid_plural "Displaying %s items"
-msgstr[0] ""
-
-#: static/horizon/js/horizon.users.js:18
-msgid "Passwords do not match."
-msgstr ""
diff --git a/horizon/management/__init__.py b/horizon/management/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/management/__init__.py
+++ /dev/null
diff --git a/horizon/management/commands/__init__.py b/horizon/management/commands/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/management/commands/__init__.py
+++ /dev/null
diff --git a/horizon/management/commands/startdash.py b/horizon/management/commands/startdash.py
deleted file mode 100644
index 9ffdd20e..00000000
--- a/horizon/management/commands/startdash.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import glob
-from optparse import make_option
-import os
-
-from django.core.management.base import CommandError
-from django.core.management.templates import TemplateCommand
-from django.utils.importlib import import_module
-
-import horizon
-
-
-class Command(TemplateCommand):
- template = os.path.join(horizon.__path__[0], "conf", "dash_template")
- option_list = TemplateCommand.option_list + (
- make_option('--target',
- dest='target',
- action='store',
- default=None,
- help='The directory in which the panel '
- 'should be created. Defaults to the '
- 'current directory. The value "auto" '
- 'may also be used to automatically '
- 'create the panel inside the specified '
- 'dashboard module.'),)
- help = ("Creates a Django app directory structure for a new dashboard "
- "with the given name in the current directory or optionally in "
- "the given directory.")
-
- def handle(self, dash_name=None, **options):
- if dash_name is None:
- raise CommandError("You must provide a dashboard name.")
-
- # Use our default template if one isn't specified.
- if not options.get("template", None):
- options["template"] = self.template
-
- # We have html templates as well, so make sure those are included.
- options["extensions"].extend(["tmpl", "html", "js", "css"])
-
- # Check that the app_name cannot be imported.
- try:
- import_module(dash_name)
- except ImportError:
- pass
- else:
- raise CommandError("%r conflicts with the name of an existing "
- "Python module and cannot be used as an app "
- "name. Please try another name." % dash_name)
-
- super(Command, self).handle('dash', dash_name, **options)
-
- target = options.pop("target", None)
- if not target:
- target = os.path.join(os.curdir, dash_name)
-
- # Rename our python template files.
- file_names = glob.glob(os.path.join(target, "*.py.tmpl"))
- for filename in file_names:
- os.rename(filename, filename[:-5])
diff --git a/horizon/management/commands/startpanel.py b/horizon/management/commands/startpanel.py
deleted file mode 100644
index 61369fa6..00000000
--- a/horizon/management/commands/startpanel.py
+++ /dev/null
@@ -1,97 +0,0 @@
-import glob
-from optparse import make_option
-import os
-
-from django.core.management.base import CommandError
-from django.core.management.templates import TemplateCommand
-from django.utils.importlib import import_module
-
-import horizon
-
-
-class Command(TemplateCommand):
- args = "[name] [dashboard name] [optional destination directory]"
- option_list = TemplateCommand.option_list + (
- make_option('--dashboard', '-d',
- dest='dashboard',
- action='store',
- default=None,
- help='The dotted python path to the '
- 'dashboard which this panel will be '
- 'registered with.'),
- make_option('--target',
- dest='target',
- action='store',
- default=None,
- help='The directory in which the panel '
- 'should be created. Defaults to the '
- 'current directory. The value "auto" '
- 'may also be used to automatically '
- 'create the panel inside the specified '
- 'dashboard module.'),)
- template = os.path.join(horizon.__path__[0], "conf", "panel_template")
- help = ("Creates a Django app directory structure for a new panel "
- "with the given name in the current directory or optionally in "
- "the given directory.")
-
- def handle(self, panel_name=None, **options):
- if panel_name is None:
- raise CommandError("You must provide a panel name.")
-
- if options.get('dashboard') is None:
- raise CommandError("You must specify the name of the dashboard "
- "this panel will be registered with using the "
- "-d or --dashboard option.")
-
- dashboard_path = options.get('dashboard')
- dashboard_mod_path = ".".join([dashboard_path, "dashboard"])
-
- # Check the the dashboard.py file in the dashboard app can be imported.
- # Add the dashboard information to our options to pass along if all
- # goes well.
- try:
- dashboard_mod = import_module(dashboard_mod_path)
- options["dash_path"] = dashboard_path
- options["dash_name"] = dashboard_path.split(".")[-1]
- except ImportError:
- raise CommandError("A dashboard.py module could not be imported "
- " from the dashboard at %r."
- % options.get("dashboard"))
-
- target = options.pop("target", None)
- if target == "auto":
- target = os.path.join(os.path.dirname(dashboard_mod.__file__),
- panel_name)
- if not os.path.exists(target):
- try:
- os.mkdir(target)
- except OSError as exc:
- raise CommandError("Unable to create panel directory: %s"
- % exc)
-
- # Use our default template if one isn't specified.
- if not options.get("template", None):
- options["template"] = self.template
-
- # We have html templates as well, so make sure those are included.
- options["extensions"].extend(["tmpl", "html"])
-
- # Check that the app_name cannot be imported.
- try:
- import_module(panel_name)
- except ImportError:
- pass
- else:
- raise CommandError("%r conflicts with the name of an existing "
- "Python module and cannot be used as an app "
- "name. Please try another name." % panel_name)
-
- super(Command, self).handle('panel', panel_name, target, **options)
-
- if not target:
- target = os.path.join(os.curdir, panel_name)
-
- # Rename our python template files.
- file_names = glob.glob(os.path.join(target, "*.py.tmpl"))
- for filename in file_names:
- os.rename(filename, filename[:-5])
diff --git a/horizon/messages.py b/horizon/messages.py
deleted file mode 100644
index 05b2ee10..00000000
--- a/horizon/messages.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Drop-in replacement for django.contrib.messages which handles Horizon's
-messaging needs (e.g. AJAX communication, etc.).
-"""
-
-from django.contrib import messages as _messages
-from django.contrib.messages import constants
-from django.utils.encoding import force_unicode
-from django.utils.safestring import SafeData
-
-
-def add_message(request, level, message, extra_tags='', fail_silently=False):
- """
- Attempts to add a message to the request using the 'messages' app.
- """
- if request.is_ajax():
- tag = constants.DEFAULT_TAGS[level]
- # if message is marked as safe, pass "safe" tag as extra_tags so that
- # client can skip HTML escape for the message when rendering
- if isinstance(message, SafeData):
- extra_tags = extra_tags + ' safe'
- request.horizon['async_messages'].append([tag,
- force_unicode(message),
- extra_tags])
- else:
- return _messages.add_message(request, level, message,
- extra_tags, fail_silently)
-
-
-def debug(request, message, extra_tags='', fail_silently=False):
- """
- Adds a message with the ``DEBUG`` level.
- """
- add_message(request, constants.DEBUG, message, extra_tags=extra_tags,
- fail_silently=fail_silently)
-
-
-def info(request, message, extra_tags='', fail_silently=False):
- """
- Adds a message with the ``INFO`` level.
- """
- add_message(request, constants.INFO, message, extra_tags=extra_tags,
- fail_silently=fail_silently)
-
-
-def success(request, message, extra_tags='', fail_silently=False):
- """
- Adds a message with the ``SUCCESS`` level.
- """
- add_message(request, constants.SUCCESS, message, extra_tags=extra_tags,
- fail_silently=fail_silently)
-
-
-def warning(request, message, extra_tags='', fail_silently=False):
- """
- Adds a message with the ``WARNING`` level.
- """
- add_message(request, constants.WARNING, message, extra_tags=extra_tags,
- fail_silently=fail_silently)
-
-
-def error(request, message, extra_tags='', fail_silently=False):
- """
- Adds a message with the ``ERROR`` level.
- """
- add_message(request, constants.ERROR, message, extra_tags=extra_tags,
- fail_silently=fail_silently)
diff --git a/horizon/middleware.py b/horizon/middleware.py
deleted file mode 100644
index 2dde4e4d..00000000
--- a/horizon/middleware.py
+++ /dev/null
@@ -1,129 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-"""
-Middleware provided and used by Horizon.
-"""
-
-import datetime
-import json
-import logging
-
-from django.conf import settings
-from django.contrib.auth import REDIRECT_FIELD_NAME
-from django.contrib.auth.views import redirect_to_login
-from django.contrib import messages as django_messages
-from django import http
-from django.http import HttpResponseRedirect
-from django import shortcuts
-from django.utils.encoding import iri_to_uri
-from django.utils import timezone
-
-from horizon import exceptions
-
-
-LOG = logging.getLogger(__name__)
-
-
-class HorizonMiddleware(object):
- """ The main Horizon middleware class. Required for use of Horizon. """
-
- def process_request(self, request):
- """ Adds data necessary for Horizon to function to the request. """
- # Activate timezone handling
- tz = request.session.get('django_timezone')
- if tz:
- timezone.activate(tz)
-
- # Check for session timeout
- timeout = 1800
- try:
- timeout = settings.SESSION_TIMEOUT
- except AttributeError:
- pass
-
- last_activity = request.session.get('last_activity', None)
- timestamp = datetime.datetime.now()
- if last_activity and (timestamp - last_activity).seconds > timeout:
- request.session.pop('last_activity')
- return HttpResponseRedirect(settings.LOGOUT_URL)
- request.session['last_activity'] = timestamp
-
- request.horizon = {'dashboard': None,
- 'panel': None,
- 'async_messages': []}
-
- def process_exception(self, request, exception):
- """
- Catches internal Horizon exception classes such as NotAuthorized,
- NotFound and Http302 and handles them gracefully.
- """
- if isinstance(exception, (exceptions.NotAuthorized,
- exceptions.NotAuthenticated)):
- auth_url = settings.LOGIN_URL
- next_url = iri_to_uri(request.get_full_path())
- if next_url != auth_url:
- field_name = REDIRECT_FIELD_NAME
- else:
- field_name = None
- login_url = request.build_absolute_uri(auth_url)
- response = redirect_to_login(next_url, login_url=login_url,
- redirect_field_name=field_name)
-
- # TODO(gabriel): Find a way to display an appropriate message to
- # the user *on* the login form...
- if request.is_ajax():
- response_401 = http.HttpResponse(status=401)
- response_401['X-Horizon-Location'] = response['location']
- return response_401
- return response
-
- # If an internal "NotFound" error gets this far, return a real 404.
- if isinstance(exception, exceptions.NotFound):
- raise http.Http404(exception)
-
- if isinstance(exception, exceptions.Http302):
- # TODO(gabriel): Find a way to display an appropriate message to
- # the user *on* the login form...
- return shortcuts.redirect(exception.location)
-
- def process_response(self, request, response):
- """
- Convert HttpResponseRedirect to HttpResponse if request is via ajax
- to allow ajax request to redirect url
- """
- if request.is_ajax():
- queued_msgs = request.horizon['async_messages']
- if type(response) == http.HttpResponseRedirect:
- # Drop our messages back into the session as per usual so they
- # don't disappear during the redirect. Not that we explicitly
- # use django's messages methods here.
- for tag, message, extra_tags in queued_msgs:
- getattr(django_messages, tag)(request, message, extra_tags)
- redirect_response = http.HttpResponse()
- redirect_response['X-Horizon-Location'] = response['location']
- return redirect_response
- if queued_msgs:
- # TODO(gabriel): When we have an async connection to the
- # client (e.g. websockets) this should be pushed to the
- # socket queue rather than being sent via a header.
- # The header method has notable drawbacks (length limits,
- # etc.) and is not meant as a long-term solution.
- response['X-Horizon-Messages'] = json.dumps(queued_msgs)
- return response
diff --git a/horizon/models.py b/horizon/models.py
deleted file mode 100644
index 6313a32f..00000000
--- a/horizon/models.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/horizon/site_urls.py b/horizon/site_urls.py
deleted file mode 100644
index 1cde0f03..00000000
--- a/horizon/site_urls.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf import settings
-from django.conf.urls.defaults import include
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-from django.views.generic import TemplateView
-
-
-urlpatterns = patterns('horizon.views',
- url(r'^home/$', 'user_home', name='user_home')
-)
-
-# Client-side i18n URLconf.
-urlpatterns += patterns('',
- url(r'^i18n/js/(?P<packages>\S+?)/$',
- 'django.views.i18n.javascript_catalog',
- name='jsi18n'),
- url(r'^i18n/setlang/$',
- 'django.views.i18n.set_language',
- name="set_language"),
- url(r'^i18n/', include('django.conf.urls.i18n'))
-)
-
-if settings.DEBUG:
- urlpatterns += patterns('',
- url(r'^qunit/$',
- TemplateView.as_view(template_name="horizon/qunit.html"),
- name='qunit_tests'))
diff --git a/horizon/static/bootstrap/js/bootstrap-datepicker.js b/horizon/static/bootstrap/js/bootstrap-datepicker.js
deleted file mode 100644
index 9ee95f31..00000000
--- a/horizon/static/bootstrap/js/bootstrap-datepicker.js
+++ /dev/null
@@ -1,470 +0,0 @@
-/* =========================================================
- * bootstrap-datepicker.js
- * http://www.eyecon.ro/bootstrap-datepicker
- * =========================================================
- * Copyright 2012 Stefan Petre
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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( $ ) {
-
- // Picker object
-
- var Datepicker = function(element, options){
- this.element = $(element);
- this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
- this.picker = $(DPGlobal.template)
- .appendTo('body')
- .on({
- click: $.proxy(this.click, this)//,
- //mousedown: $.proxy(this.mousedown, this)
- });
- this.isInput = this.element.is('input');
- this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
-
- if (this.isInput) {
- this.element.on({
- focus: $.proxy(this.show, this),
- //blur: $.proxy(this.hide, this),
- keyup: $.proxy(this.update, this)
- });
- } else {
- if (this.component){
- this.component.on('click', $.proxy(this.show, this));
- } else {
- this.element.on('click', $.proxy(this.show, this));
- }
- }
-
- this.minViewMode = options.minViewMode||this.element.data('date-minviewmode')||0;
- if (typeof this.minViewMode === 'string') {
- switch (this.minViewMode) {
- case 'months':
- this.minViewMode = 1;
- break;
- case 'years':
- this.minViewMode = 2;
- break;
- default:
- this.minViewMode = 0;
- break;
- }
- }
- this.viewMode = options.viewMode||this.element.data('date-viewmode')||0;
- if (typeof this.viewMode === 'string') {
- switch (this.viewMode) {
- case 'months':
- this.viewMode = 1;
- break;
- case 'years':
- this.viewMode = 2;
- break;
- default:
- this.viewMode = 0;
- break;
- }
- }
- this.startViewMode = this.viewMode;
- this.weekStart = options.weekStart||this.element.data('date-weekstart')||0;
- this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1;
- this.onRender = options.onRender;
- this.fillDow();
- this.fillMonths();
- this.update();
- this.showMode();
- };
-
- Datepicker.prototype = {
- constructor: Datepicker,
-
- show: function(e) {
- this.picker.show();
- this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
- this.place();
- $(window).on('resize', $.proxy(this.place, this));
- if (e ) {
- e.stopPropagation();
- e.preventDefault();
- }
- if (!this.isInput) {
- }
- var that = this;
- $(document).on('mousedown', function(ev){
- if ($(ev.target).closest('.datepicker').length == 0) {
- that.hide();
- }
- });
- this.element.trigger({
- type: 'show',
- date: this.date
- });
- },
-
- hide: function(){
- this.picker.hide();
- $(window).off('resize', this.place);
- this.viewMode = this.startViewMode;
- this.showMode();
- if (!this.isInput) {
- $(document).off('mousedown', this.hide);
- }
- //this.set();
- this.element.trigger({
- type: 'hide',
- date: this.date
- });
- },
-
- set: function() {
- var formated = DPGlobal.formatDate(this.date, this.format);
- if (!this.isInput) {
- if (this.component){
- this.element.find('input').prop('value', formated);
- }
- this.element.data('date', formated);
- } else {
- this.element.prop('value', formated);
- }
- },
-
- setValue: function(newDate) {
- if (typeof newDate === 'string') {
- this.date = DPGlobal.parseDate(newDate, this.format);
- } else {
- this.date = new Date(newDate);
- }
- this.set();
- this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
- this.fill();
- },
-
- place: function(){
- var offset = this.component ? this.component.offset() : this.element.offset();
- this.picker.css({
- top: offset.top + this.height,
- left: offset.left
- });
- },
-
- update: function(newDate){
- this.date = DPGlobal.parseDate(
- typeof newDate === 'string' ? newDate : (this.isInput ? this.element.prop('value') : this.element.data('date')),
- this.format
- );
- this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
- this.fill();
- },
-
- fillDow: function(){
- var dowCnt = this.weekStart;
- var html = '<tr>';
- while (dowCnt < this.weekStart + 7) {
- html += '<th class="dow">'+DPGlobal.dates.daysMin[(dowCnt++)%7]+'</th>';
- }
- html += '</tr>';
- this.picker.find('.datepicker-days thead').append(html);
- },
-
- fillMonths: function(){
- var html = '';
- var i = 0
- while (i < 12) {
- html += '<span class="month">'+DPGlobal.dates.monthsShort[i++]+'</span>';
- }
- this.picker.find('.datepicker-months td').append(html);
- },
-
- fill: function() {
- var d = new Date(this.viewDate),
- year = d.getFullYear(),
- month = d.getMonth(),
- currentDate = this.date.valueOf();
- this.picker.find('.datepicker-days th:eq(1)')
- .text(DPGlobal.dates.months[month]+' '+year);
- var prevMonth = new Date(year, month-1, 28,0,0,0,0),
- day = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth());
- prevMonth.setDate(day);
- prevMonth.setDate(day - (prevMonth.getDay() - this.weekStart + 7)%7);
- var nextMonth = new Date(prevMonth);
- nextMonth.setDate(nextMonth.getDate() + 42);
- nextMonth = nextMonth.valueOf();
- html = [];
- var clsName;
- while(prevMonth.valueOf() < nextMonth) {
- if (prevMonth.getDay() === this.weekStart) {
- html.push('<tr>');
- }
- clsName = this.onRender(prevMonth);
- if (prevMonth.getMonth() < month) {
- clsName += ' old';
- } else if (prevMonth.getMonth() > month) {
- clsName += ' new';
- }
- if (prevMonth.valueOf() === currentDate) {
- clsName += ' active';
- }
- html.push('<td class="day '+clsName+'">'+prevMonth.getDate() + '</td>');
- if (prevMonth.getDay() === this.weekEnd) {
- html.push('</tr>');
- }
- prevMonth.setDate(prevMonth.getDate()+1);
- }
- this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
- var currentYear = this.date.getFullYear();
-
- var months = this.picker.find('.datepicker-months')
- .find('th:eq(1)')
- .text(year)
- .end()
- .find('span').removeClass('active');
- if (currentYear === year) {
- months.eq(this.date.getMonth()).addClass('active');
- }
-
- html = '';
- year = parseInt(year/10, 10) * 10;
- var yearCont = this.picker.find('.datepicker-years')
- .find('th:eq(1)')
- .text(year + '-' + (year + 9))
- .end()
- .find('td');
- year -= 1;
- for (var i = -1; i < 11; i++) {
- html += '<span class="year'+(i === -1 || i === 10 ? ' old' : '')+(currentYear === year ? ' active' : '')+'">'+year+'</span>';
- year += 1;
- }
- yearCont.html(html);
- },
-
- click: function(e) {
- e.stopPropagation();
- e.preventDefault();
- var target = $(e.target).closest('span, td, th');
- if (target.length === 1) {
- switch(target[0].nodeName.toLowerCase()) {
- case 'th':
- switch(target[0].className) {
- case 'switch':
- this.showMode(1);
- break;
- case 'prev':
- case 'next':
- this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call(
- this.viewDate,
- this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) +
- DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1)
- );
- this.fill();
- this.set();
- break;
- }
- break;
- case 'span':
- if (target.is('.month')) {
- var month = target.parent().find('span').index(target);
- this.viewDate.setMonth(month);
- } else {
- var year = parseInt(target.text(), 10)||0;
- this.viewDate.setFullYear(year);
- }
- if (this.viewMode !== 0) {
- this.date = new Date(this.viewDate);
- this.element.trigger({
- type: 'changeDate',
- date: this.date,
- viewMode: DPGlobal.modes[this.viewMode].clsName
- });
- }
- this.showMode(-1);
- this.fill();
- this.set();
- break;
- case 'td':
- if (target.is('.day') && !target.is('.disabled')){
- var day = parseInt(target.text(), 10)||1;
- var month = this.viewDate.getMonth();
- if (target.is('.old')) {
- month -= 1;
- } else if (target.is('.new')) {
- month += 1;
- }
- var year = this.viewDate.getFullYear();
- this.date = new Date(year, month, day,0,0,0,0);
- this.viewDate = new Date(year, month, Math.min(28, day),0,0,0,0);
- this.fill();
- this.set();
- this.element.trigger({
- type: 'changeDate',
- date: this.date,
- viewMode: DPGlobal.modes[this.viewMode].clsName
- });
- }
- break;
- }
- }
- },
-
- mousedown: function(e){
- e.stopPropagation();
- e.preventDefault();
- },
-
- showMode: function(dir) {
- if (dir) {
- this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
- }
- this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
- }
- };
-
- $.fn.datepicker = function ( option, val ) {
- return this.each(function () {
- var $this = $(this),
- data = $this.data('datepicker'),
- options = typeof option === 'object' && option;
- if (!data) {
- $this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
- }
- if (typeof option === 'string') data[option](val);
- });
- };
-
- $.fn.datepicker.defaults = {
- onRender: function(date) {
- return '';
- }
- };
- $.fn.datepicker.Constructor = Datepicker;
-
- var DPGlobal = {
- modes: [
- {
- clsName: 'days',
- navFnc: 'Month',
- navStep: 1
- },
- {
- clsName: 'months',
- navFnc: 'FullYear',
- navStep: 1
- },
- {
- clsName: 'years',
- navFnc: 'FullYear',
- navStep: 10
- }],
- dates:{
- days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
- daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
- daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
- months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
- monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
- },
- isLeapYear: function (year) {
- return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
- },
- getDaysInMonth: function (year, month) {
- return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
- },
- parseFormat: function(format){
- var separator = format.match(/[.\/\-\s].*?/),
- parts = format.split(/\W+/);
- if (!separator || !parts || parts.length === 0){
- throw new Error("Invalid date format.");
- }
- return {separator: separator, parts: parts};
- },
- parseDate: function(date, format) {
- var parts = date.split(format.separator),
- date = new Date(),
- val;
- date.setHours(0);
- date.setMinutes(0);
- date.setSeconds(0);
- date.setMilliseconds(0);
- if (parts.length === format.parts.length) {
- var year = date.getFullYear(), day = date.getDate(), month = date.getMonth();
- for (var i=0, cnt = format.parts.length; i < cnt; i++) {
- val = parseInt(parts[i], 10)||1;
- switch(format.parts[i]) {
- case 'dd':
- case 'd':
- day = val;
- date.setDate(val);
- break;
- case 'mm':
- case 'm':
- month = val - 1;
- date.setMonth(val - 1);
- break;
- case 'yy':
- year = 2000 + val;
- date.setFullYear(2000 + val);
- break;
- case 'yyyy':
- year = val;
- date.setFullYear(val);
- break;
- }
- }
- date = new Date(year, month, day, 0 ,0 ,0);
- }
- return date;
- },
- formatDate: function(date, format){
- var val = {
- d: date.getDate(),
- m: date.getMonth() + 1,
- yy: date.getFullYear().toString().substring(2),
- yyyy: date.getFullYear()
- };
- val.dd = (val.d < 10 ? '0' : '') + val.d;
- val.mm = (val.m < 10 ? '0' : '') + val.m;
- var date = [];
- for (var i=0, cnt = format.parts.length; i < cnt; i++) {
- date.push(val[format.parts[i]]);
- }
- return date.join(format.separator);
- },
- headTemplate: '<thead>'+
- '<tr>'+
- '<th class="prev">&lsaquo;</th>'+
- '<th colspan="5" class="switch"></th>'+
- '<th class="next">&rsaquo;</th>'+
- '</tr>'+
- '</thead>',
- contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
- };
- DPGlobal.template = '<div class="datepicker dropdown-menu">'+
- '<div class="datepicker-days">'+
- '<table class=" table-condensed">'+
- DPGlobal.headTemplate+
- '<tbody></tbody>'+
- '</table>'+
- '</div>'+
- '<div class="datepicker-months">'+
- '<table class="table-condensed">'+
- DPGlobal.headTemplate+
- DPGlobal.contTemplate+
- '</table>'+
- '</div>'+
- '<div class="datepicker-years">'+
- '<table class="table-condensed">'+
- DPGlobal.headTemplate+
- DPGlobal.contTemplate+
- '</table>'+
- '</div>'+
- '</div>';
-
-}( window.jQuery ); \ No newline at end of file
diff --git a/horizon/static/bootstrap/js/bootstrap.js b/horizon/static/bootstrap/js/bootstrap.js
deleted file mode 100644
index 4412304e..00000000
--- a/horizon/static/bootstrap/js/bootstrap.js
+++ /dev/null
@@ -1,1720 +0,0 @@
-/* ===================================================
- * bootstrap-transition.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#transitions
- * ===================================================
- * Copyright 2012 Twitter, 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( $ ) {
-
- $(function () {
-
- "use strict"
-
- /* CSS TRANSITION SUPPORT (https://gist.github.com/373874)
- * ======================================================= */
-
- $.support.transition = (function () {
- var thisBody = document.body || document.documentElement
- , thisStyle = thisBody.style
- , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined
-
- return support && {
- end: (function () {
- var transitionEnd = "TransitionEnd"
- if ( $.browser.webkit ) {
- transitionEnd = "webkitTransitionEnd"
- } else if ( $.browser.mozilla ) {
- transitionEnd = "transitionend"
- } else if ( $.browser.opera ) {
- transitionEnd = "oTransitionEnd"
- }
- return transitionEnd
- }())
- }
- })()
-
- })
-
-}( window.jQuery );/* ==========================================================
- * bootstrap-alert.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#alerts
- * ==========================================================
- * Copyright 2012 Twitter, 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"
-
- /* ALERT CLASS DEFINITION
- * ====================== */
-
- var dismiss = '[data-dismiss="alert"]'
- , Alert = function ( el ) {
- $(el).on('click', dismiss, this.close)
- }
-
- Alert.prototype = {
-
- constructor: Alert
-
- , close: function ( e ) {
- var $this = $(this)
- , selector = $this.attr('data-target')
- , $parent
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
- }
-
- $parent = $(selector)
- $parent.trigger('close')
-
- e && e.preventDefault()
-
- $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
-
- $parent
- .trigger('close')
- .removeClass('in')
-
- function removeElement() {
- $parent
- .trigger('closed')
- .remove()
- }
-
- $.support.transition && $parent.hasClass('fade') ?
- $parent.on($.support.transition.end, removeElement) :
- removeElement()
- }
-
- }
-
-
- /* ALERT PLUGIN DEFINITION
- * ======================= */
-
- $.fn.alert = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('alert')
- if (!data) $this.data('alert', (data = new Alert(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
-
- $.fn.alert.Constructor = Alert
-
-
- /* ALERT DATA-API
- * ============== */
-
- $(function () {
- $('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
- })
-
-}( window.jQuery );/* ============================================================
- * bootstrap-button.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#buttons
- * ============================================================
- * Copyright 2012 Twitter, 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"
-
- /* BUTTON PUBLIC CLASS DEFINITION
- * ============================== */
-
- var Button = function ( element, options ) {
- this.$element = $(element)
- this.options = $.extend({}, $.fn.button.defaults, options)
- }
-
- Button.prototype = {
-
- constructor: Button
-
- , setState: function ( state ) {
- var d = 'disabled'
- , $el = this.$element
- , data = $el.data()
- , val = $el.is('input') ? 'val' : 'html'
-
- state = state + 'Text'
- data.resetText || $el.data('resetText', $el[val]())
-
- $el[val](data[state] || this.options[state])
-
- // push to event loop to allow forms to submit
- setTimeout(function () {
- state == 'loadingText' ?
- $el.addClass(d).attr(d, d) :
- $el.removeClass(d).removeAttr(d)
- }, 0)
- }
-
- , toggle: function () {
- var $parent = this.$element.parent('[data-toggle="buttons-radio"]')
-
- $parent && $parent
- .find('.active')
- .removeClass('active')
-
- this.$element.toggleClass('active')
- }
-
- }
-
-
- /* BUTTON PLUGIN DEFINITION
- * ======================== */
-
- $.fn.button = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('button')
- , options = typeof option == 'object' && option
- if (!data) $this.data('button', (data = new Button(this, options)))
- if (option == 'toggle') data.toggle()
- else if (option) data.setState(option)
- })
- }
-
- $.fn.button.defaults = {
- loadingText: 'loading...'
- }
-
- $.fn.button.Constructor = Button
-
-
- /* BUTTON DATA-API
- * =============== */
-
- $(function () {
- $('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
- var $btn = $(e.target)
- if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
- $btn.button('toggle')
- })
- })
-
-}( window.jQuery );/* ==========================================================
- * bootstrap-carousel.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#carousel
- * ==========================================================
- * Copyright 2012 Twitter, 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"
-
- /* CAROUSEL CLASS DEFINITION
- * ========================= */
-
- var Carousel = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, $.fn.carousel.defaults, options)
- this.options.slide && this.slide(this.options.slide)
- }
-
- Carousel.prototype = {
-
- cycle: function () {
- this.interval = setInterval($.proxy(this.next, this), this.options.interval)
- return this
- }
-
- , to: function (pos) {
- var $active = this.$element.find('.active')
- , children = $active.parent().children()
- , activePos = children.index($active)
- , that = this
-
- if (pos > (children.length - 1) || pos < 0) return
-
- if (this.sliding) {
- return this.$element.one('slid', function () {
- that.to(pos)
- })
- }
-
- if (activePos == pos) {
- return this.pause().cycle()
- }
-
- return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
- }
-
- , pause: function () {
- clearInterval(this.interval)
- this.interval = null
- return this
- }
-
- , next: function () {
- if (this.sliding) return
- return this.slide('next')
- }
-
- , prev: function () {
- if (this.sliding) return
- return this.slide('prev')
- }
-
- , slide: function (type, next) {
- var $active = this.$element.find('.active')
- , $next = next || $active[type]()
- , isCycling = this.interval
- , direction = type == 'next' ? 'left' : 'right'
- , fallback = type == 'next' ? 'first' : 'last'
- , that = this
-
- if (!$next.length) return
-
- this.sliding = true
-
- isCycling && this.pause()
-
- $next = $next.length ? $next : this.$element.find('.item')[fallback]()
-
- if (!$.support.transition && this.$element.hasClass('slide')) {
- this.$element.trigger('slide')
- $active.removeClass('active')
- $next.addClass('active')
- this.sliding = false
- this.$element.trigger('slid')
- } else {
- $next.addClass(type)
- $next[0].offsetWidth // force reflow
- $active.addClass(direction)
- $next.addClass(direction)
- this.$element.trigger('slide')
- this.$element.one($.support.transition.end, function () {
- $next.removeClass([type, direction].join(' ')).addClass('active')
- $active.removeClass(['active', direction].join(' '))
- that.sliding = false
- setTimeout(function () { that.$element.trigger('slid') }, 0)
- })
- }
-
- isCycling && this.cycle()
-
- return this
- }
-
- }
-
-
- /* CAROUSEL PLUGIN DEFINITION
- * ========================== */
-
- $.fn.carousel = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('carousel')
- , options = typeof option == 'object' && option
- if (!data) $this.data('carousel', (data = new Carousel(this, options)))
- if (typeof option == 'number') data.to(option)
- else if (typeof option == 'string' || (option = options.slide)) data[option]()
- else data.cycle()
- })
- }
-
- $.fn.carousel.defaults = {
- interval: 5000
- }
-
- $.fn.carousel.Constructor = Carousel
-
-
- /* CAROUSEL DATA-API
- * ================= */
-
- $(function () {
- $('body').on('click.carousel.data-api', '[data-slide]', function ( e ) {
- var $this = $(this), href
- , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
- , options = !$target.data('modal') && $.extend({}, $target.data(), $this.data())
- $target.carousel(options)
- e.preventDefault()
- })
- })
-
-}( window.jQuery );/* =============================================================
- * bootstrap-collapse.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#collapse
- * =============================================================
- * Copyright 2012 Twitter, 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 Collapse = function ( element, options ) {
- this.$element = $(element)
- this.options = $.extend({}, $.fn.collapse.defaults, options)
-
- if (this.options["parent"]) {
- this.$parent = $(this.options["parent"])
- }
-
- this.options.toggle && this.toggle()
- }
-
- Collapse.prototype = {
-
- constructor: Collapse
-
- , dimension: function () {
- var hasWidth = this.$element.hasClass('width')
- return hasWidth ? 'width' : 'height'
- }
-
- , show: function () {
- var dimension = this.dimension()
- , scroll = $.camelCase(['scroll', dimension].join('-'))
- , actives = this.$parent && this.$parent.find('.in')
- , hasData
-
- if (actives && actives.length) {
- hasData = actives.data('collapse')
- actives.collapse('hide')
- hasData || actives.data('collapse', null)
- }
-
- this.$element[dimension](0)
- this.transition('addClass', 'show', 'shown')
- this.$element[dimension](this.$element[0][scroll])
-
- }
-
- , hide: function () {
- var dimension = this.dimension()
- this.reset(this.$element[dimension]())
- this.transition('removeClass', 'hide', 'hidden')
- this.$element[dimension](0)
- }
-
- , reset: function ( size ) {
- var dimension = this.dimension()
-
- this.$element
- .removeClass('collapse')
- [dimension](size || 'auto')
- [0].offsetWidth
-
- this.$element.addClass('collapse')
- }
-
- , transition: function ( method, startEvent, completeEvent ) {
- var that = this
- , complete = function () {
- if (startEvent == 'show') that.reset()
- that.$element.trigger(completeEvent)
- }
-
- this.$element
- .trigger(startEvent)
- [method]('in')
-
- $.support.transition && this.$element.hasClass('collapse') ?
- this.$element.one($.support.transition.end, complete) :
- complete()
- }
-
- , toggle: function () {
- this[this.$element.hasClass('in') ? 'hide' : 'show']()
- }
-
- }
-
- /* COLLAPSIBLE PLUGIN DEFINITION
- * ============================== */
-
- $.fn.collapse = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('collapse')
- , options = typeof option == 'object' && option
- if (!data) $this.data('collapse', (data = new Collapse(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.collapse.defaults = {
- toggle: true
- }
-
- $.fn.collapse.Constructor = Collapse
-
-
- /* COLLAPSIBLE DATA-API
- * ==================== */
-
- $(function () {
- $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {
- var $this = $(this), href
- , target = $this.attr('data-target')
- || e.preventDefault()
- || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
- , option = $(target).data('collapse') ? 'toggle' : $this.data()
- $(target).collapse(option)
- })
- })
-
-}( window.jQuery );/* ============================================================
- * bootstrap-dropdown.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#dropdowns
- * ============================================================
- * Copyright 2012 Twitter, 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"
-
- /* DROPDOWN CLASS DEFINITION
- * ========================= */
-
- var toggle = '[data-toggle="dropdown"]'
- , Dropdown = function ( element ) {
- var $el = $(element).on('click.dropdown.data-api', this.toggle)
- $('html').on('click.dropdown.data-api', function () {
- $el.parent().removeClass('open')
- })
- }
-
- Dropdown.prototype = {
-
- constructor: Dropdown
-
- , toggle: function ( e ) {
- var $this = $(this)
- , selector = $this.attr('data-target')
- , $parent
- , isActive
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
- }
-
- $parent = $(selector)
- $parent.length || ($parent = $this.parent())
-
- isActive = $parent.hasClass('open')
-
- clearMenus()
- !isActive && $parent.toggleClass('open')
-
- return false
- }
-
- }
-
- function clearMenus() {
- $(toggle).parent().removeClass('open')
- }
-
-
- /* DROPDOWN PLUGIN DEFINITION
- * ========================== */
-
- $.fn.dropdown = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('dropdown')
- if (!data) $this.data('dropdown', (data = new Dropdown(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
-
- $.fn.dropdown.Constructor = Dropdown
-
-
- /* APPLY TO STANDARD DROPDOWN ELEMENTS
- * =================================== */
-
- $(function () {
- $('html').on('click.dropdown.data-api', clearMenus)
- $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)
- })
-
-}( window.jQuery );/* =========================================================
- * bootstrap-modal.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#modals
- * =========================================================
- * Copyright 2012 Twitter, 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"
-
- /* MODAL CLASS DEFINITION
- * ====================== */
-
- var Modal = function ( content, options ) {
- this.options = options
- this.$element = $(content)
- .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
- }
-
- Modal.prototype = {
-
- constructor: Modal
-
- , toggle: function () {
- return this[!this.isShown ? 'show' : 'hide']()
- }
-
- , show: function () {
- var that = this
-
- if (this.isShown) return
-
- $('body').addClass('modal-open')
-
- this.isShown = true
- this.$element.trigger('show')
-
- escape.call(this)
- backdrop.call(this, function () {
- var transition = $.support.transition && that.$element.hasClass('fade')
-
- !that.$element.parent().length && that.$element.appendTo(document.body) //don't move modals dom position
-
- that.$element
- .show()
-
- if (transition) {
- that.$element[0].offsetWidth // force reflow
- }
-
- that.$element.addClass('in')
-
- transition ?
- that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
- that.$element.trigger('shown')
-
- })
- }
-
- , hide: function ( e ) {
- e && e.preventDefault()
-
- if (!this.isShown) return
-
- var that = this
- this.isShown = false
-
- $('body').removeClass('modal-open')
-
- escape.call(this)
-
- this.$element
- .trigger('hide')
- .removeClass('in')
-
- $.support.transition && this.$element.hasClass('fade') ?
- hideWithTransition.call(this) :
- hideModal.call(this)
- }
-
- }
-
-
- /* MODAL PRIVATE METHODS
- * ===================== */
-
- function hideWithTransition() {
- var that = this
- , timeout = setTimeout(function () {
- that.$element.off($.support.transition.end)
- hideModal.call(that)
- }, 500)
-
- this.$element.one($.support.transition.end, function () {
- clearTimeout(timeout)
- hideModal.call(that)
- })
- }
-
- function hideModal( that ) {
- this.$element
- .hide()
- .trigger('hidden')
-
- backdrop.call(this)
- }
-
- function backdrop( callback ) {
- var that = this
- , animate = this.$element.hasClass('fade') ? 'fade' : ''
-
- if (this.isShown && this.options.backdrop) {
- var doAnimate = $.support.transition && animate
-
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
- .appendTo(document.body)
-
- if (this.options.backdrop != 'static') {
- this.$backdrop.click($.proxy(this.hide, this))
- }
-
- if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
-
- this.$backdrop.addClass('in')
-
- doAnimate ?
- this.$backdrop.one($.support.transition.end, callback) :
- callback()
-
- } else if (!this.isShown && this.$backdrop) {
- this.$backdrop.removeClass('in')
-
- $.support.transition && this.$element.hasClass('fade')?
- this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
- removeBackdrop.call(this)
-
- } else if (callback) {
- callback()
- }
- }
-
- function removeBackdrop() {
- this.$backdrop.remove()
- this.$backdrop = null
- }
-
- function escape() {
- var that = this
- if (this.isShown && this.options.keyboard) {
- $(document).on('keyup.dismiss.modal', function ( e ) {
- e.which == 27 && that.hide()
- })
- } else if (!this.isShown) {
- $(document).off('keyup.dismiss.modal')
- }
- }
-
-
- /* MODAL PLUGIN DEFINITION
- * ======================= */
-
- $.fn.modal = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('modal')
- , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
- if (!data) $this.data('modal', (data = new Modal(this, options)))
- if (typeof option == 'string') data[option]()
- else if (options.show) data.show()
- })
- }
-
- $.fn.modal.defaults = {
- backdrop: true
- , keyboard: true
- , show: true
- }
-
- $.fn.modal.Constructor = Modal
-
-
- /* MODAL DATA-API
- * ============== */
-
- $(function () {
- $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
- var $this = $(this), href
- , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
- , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())
-
- e.preventDefault()
- $target.modal(option)
- })
- })
-
-}( window.jQuery );/* ===========================================================
- * bootstrap-tooltip.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#tooltips
- * Inspired by the original jQuery.tipsy by Jason Frame
- * ===========================================================
- * Copyright 2012 Twitter, 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"
-
- /* TOOLTIP PUBLIC CLASS DEFINITION
- * =============================== */
-
- var Tooltip = function ( element, options ) {
- this.init('tooltip', element, options)
- }
-
- Tooltip.prototype = {
-
- constructor: Tooltip
-
- , init: function ( type, element, options ) {
- var eventIn
- , eventOut
-
- this.type = type
- this.$element = $(element)
- this.options = this.getOptions(options)
- this.enabled = true
-
- if (this.options.trigger != 'manual') {
- eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
- eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
- this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
- this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
- }
-
- this.options.selector ?
- (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
- this.fixTitle()
- }
-
- , getOptions: function ( options ) {
- options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
-
- if (options.delay && typeof options.delay == 'number') {
- options.delay = {
- show: options.delay
- , hide: options.delay
- }
- }
-
- return options
- }
-
- , enter: function ( e ) {
- var self = $(e.currentTarget)[this.type](this._options).data(this.type)
-
- if (!self.options.delay || !self.options.delay.show) {
- self.show()
- } else {
- self.hoverState = 'in'
- setTimeout(function() {
- if (self.hoverState == 'in') {
- self.show()
- }
- }, self.options.delay.show)
- }
- }
-
- , leave: function ( e ) {
- var self = $(e.currentTarget)[this.type](this._options).data(this.type)
-
- if (!self.options.delay || !self.options.delay.hide) {
- self.hide()
- } else {
- self.hoverState = 'out'
- setTimeout(function() {
- if (self.hoverState == 'out') {
- self.hide()
- }
- }, self.options.delay.hide)
- }
- }
-
- , show: function () {
- var $tip
- , inside
- , pos
- , actualWidth
- , actualHeight
- , placement
- , tp
-
- if (this.hasContent() && this.enabled) {
- $tip = this.tip()
- this.setContent()
-
- if (this.options.animation) {
- $tip.addClass('fade')
- }
-
- placement = typeof this.options.placement == 'function' ?
- this.options.placement.call(this, $tip[0], this.$element[0]) :
- this.options.placement
-
- inside = /in/.test(placement)
-
- $tip
- .remove()
- .css({ top: 0, left: 0, display: 'block' })
- .appendTo(inside ? this.$element : document.body)
-
- pos = this.getPosition(inside)
-
- actualWidth = $tip[0].offsetWidth
- actualHeight = $tip[0].offsetHeight
-
- switch (inside ? placement.split(' ')[1] : placement) {
- case 'bottom':
- tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
- break
- case 'top':
- tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
- break
- case 'left':
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
- break
- case 'right':
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
- break
- }
-
- $tip
- .css(tp)
- .addClass(placement)
- .addClass('in')
- }
- }
-
- , setContent: function () {
- var $tip = this.tip()
- $tip.find('.tooltip-inner').html(this.getTitle())
- $tip.removeClass('fade in top bottom left right')
- }
-
- , hide: function () {
- var that = this
- , $tip = this.tip()
-
- $tip.removeClass('in')
-
- function removeWithAnimation() {
- var timeout = setTimeout(function () {
- $tip.off($.support.transition.end).remove()
- }, 500)
-
- $tip.one($.support.transition.end, function () {
- clearTimeout(timeout)
- $tip.remove()
- })
- }
-
- $.support.transition && this.$tip.hasClass('fade') ?
- removeWithAnimation() :
- $tip.remove()
- }
-
- , fixTitle: function () {
- var $e = this.$element
- if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
- $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
- }
- }
-
- , hasContent: function () {
- return this.getTitle()
- }
-
- , getPosition: function (inside) {
- return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
- width: this.$element[0].offsetWidth
- , height: this.$element[0].offsetHeight
- })
- }
-
- , getTitle: function () {
- var title
- , $e = this.$element
- , o = this.options
-
- title = $e.attr('data-original-title')
- || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
-
- title = title.toString().replace(/(^\s*|\s*$)/, "")
-
- return title
- }
-
- , tip: function () {
- return this.$tip = this.$tip || $(this.options.template)
- }
-
- , validate: function () {
- if (!this.$element[0].parentNode) {
- this.hide()
- this.$element = null
- this.options = null
- }
- }
-
- , enable: function () {
- this.enabled = true
- }
-
- , disable: function () {
- this.enabled = false
- }
-
- , toggleEnabled: function () {
- this.enabled = !this.enabled
- }
-
- , toggle: function () {
- this[this.tip().hasClass('in') ? 'hide' : 'show']()
- }
-
- }
-
-
- /* TOOLTIP PLUGIN DEFINITION
- * ========================= */
-
- $.fn.tooltip = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('tooltip')
- , options = typeof option == 'object' && option
- if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.tooltip.Constructor = Tooltip
-
- $.fn.tooltip.defaults = {
- animation: true
- , delay: 0
- , selector: false
- , placement: 'top'
- , trigger: 'hover'
- , title: ''
- , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
- }
-
-}( window.jQuery );/* ===========================================================
- * bootstrap-popover.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#popovers
- * ===========================================================
- * Copyright 2012 Twitter, 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 Popover = function ( element, options ) {
- this.init('popover', element, options)
- }
-
- /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
- ========================================== */
-
- Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
-
- constructor: Popover
-
- , setContent: function () {
- var $tip = this.tip()
- , title = this.getTitle()
- , content = this.getContent()
-
- $tip.find('.popover-title')[ $.type(title) == 'object' ? 'append' : 'html' ](title)
- $tip.find('.popover-content > *')[ $.type(content) == 'object' ? 'append' : 'html' ](content)
-
- $tip.removeClass('fade top bottom left right in')
- }
-
- , hasContent: function () {
- return this.getTitle() || this.getContent()
- }
-
- , getContent: function () {
- var content
- , $e = this.$element
- , o = this.options
-
- content = $e.attr('data-content')
- || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
-
- content = content.toString().replace(/(^\s*|\s*$)/, "")
-
- return content
- }
-
- , tip: function() {
- if (!this.$tip) {
- this.$tip = $(this.options.template)
- }
- return this.$tip
- }
-
- })
-
-
- /* POPOVER PLUGIN DEFINITION
- * ======================= */
-
- $.fn.popover = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('popover')
- , options = typeof option == 'object' && option
- if (!data) $this.data('popover', (data = new Popover(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.popover.Constructor = Popover
-
- $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
- placement: 'right'
- , content: ''
- , template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
- })
-
-}( window.jQuery );/* =============================================================
- * bootstrap-scrollspy.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#scrollspy
- * =============================================================
- * Copyright 2012 Twitter, 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"
-
- /* SCROLLSPY CLASS DEFINITION
- * ========================== */
-
- function ScrollSpy( element, options) {
- var process = $.proxy(this.process, this)
- , $element = $(element).is('body') ? $(window) : $(element)
- , href
- this.options = $.extend({}, $.fn.scrollspy.defaults, options)
- this.$scrollElement = $element.on('scroll.scroll.data-api', process)
- this.selector = (this.options.target
- || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
- || '') + ' .nav li > a'
- this.$body = $('body').on('click.scroll.data-api', this.selector, process)
- this.refresh()
- this.process()
- }
-
- ScrollSpy.prototype = {
-
- constructor: ScrollSpy
-
- , refresh: function () {
- this.targets = this.$body
- .find(this.selector)
- .map(function () {
- var href = $(this).attr('href')
- return /^#\w/.test(href) && $(href).length ? href : null
- })
-
- this.offsets = $.map(this.targets, function (id) {
- return $(id).position().top
- })
- }
-
- , process: function () {
- var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
- , offsets = this.offsets
- , targets = this.targets
- , activeTarget = this.activeTarget
- , i
-
- for (i = offsets.length; i--;) {
- activeTarget != targets[i]
- && scrollTop >= offsets[i]
- && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
- && this.activate( targets[i] )
- }
- }
-
- , activate: function (target) {
- var active
-
- this.activeTarget = target
-
- this.$body
- .find(this.selector).parent('.active')
- .removeClass('active')
-
- active = this.$body
- .find(this.selector + '[href="' + target + '"]')
- .parent('li')
- .addClass('active')
-
- if ( active.parent('.dropdown-menu') ) {
- active.closest('li.dropdown').addClass('active')
- }
- }
-
- }
-
-
- /* SCROLLSPY PLUGIN DEFINITION
- * =========================== */
-
- $.fn.scrollspy = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('scrollspy')
- , options = typeof option == 'object' && option
- if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.scrollspy.Constructor = ScrollSpy
-
- $.fn.scrollspy.defaults = {
- offset: 10
- }
-
-
- /* SCROLLSPY DATA-API
- * ================== */
-
- $(function () {
- $('[data-spy="scroll"]').each(function () {
- var $spy = $(this)
- $spy.scrollspy($spy.data())
- })
- })
-
-}( window.jQuery );/* ========================================================
- * bootstrap-tab.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#tabs
- * ========================================================
- * Copyright 2012 Twitter, 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"
-
- /* TAB CLASS DEFINITION
- * ==================== */
-
- var Tab = function ( element ) {
- this.element = $(element)
- }
-
- Tab.prototype = {
-
- constructor: Tab
-
- , show: function () {
- var $this = this.element
- , $ul = $this.closest('ul:not(.dropdown-menu)')
- , selector = $this.attr('data-target')
- , previous
- , $target
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
- }
-
- if ( $this.parent('li').hasClass('active') ) return
-
- previous = $ul.find('.active a').last()[0]
-
- $this.trigger({
- type: 'show'
- , relatedTarget: previous
- })
-
- $target = $(selector)
-
- this.activate($this.parent('li'), $ul)
- this.activate($target, $target.parent(), function () {
- $this.trigger({
- type: 'shown'
- , relatedTarget: previous
- })
- })
- }
-
- , activate: function ( element, container, callback) {
- var $active = container.find('> .active')
- , transition = callback
- && $.support.transition
- && $active.hasClass('fade')
-
- function next() {
- $active
- .removeClass('active')
- .find('> .dropdown-menu > .active')
- .removeClass('active')
-
- element.addClass('active')
-
- if (transition) {
- element[0].offsetWidth // reflow for transition
- element.addClass('in')
- } else {
- element.removeClass('fade')
- }
-
- if ( element.parent('.dropdown-menu') ) {
- element.closest('li.dropdown').addClass('active')
- }
-
- callback && callback()
- }
-
- transition ?
- $active.one($.support.transition.end, next) :
- next()
-
- $active.removeClass('in')
- }
- }
-
-
- /* TAB PLUGIN DEFINITION
- * ===================== */
-
- $.fn.tab = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('tab')
- if (!data) $this.data('tab', (data = new Tab(this)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.tab.Constructor = Tab
-
-
- /* TAB DATA-API
- * ============ */
-
- $(function () {
- $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
- e.preventDefault()
- $(this).tab('show')
- })
- })
-
-}( window.jQuery );/* =============================================================
- * bootstrap-typeahead.js v2.0.1
- * http://twitter.github.com/bootstrap/javascript.html#typeahead
- * =============================================================
- * Copyright 2012 Twitter, 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 Typeahead = function ( element, options ) {
- this.$element = $(element)
- this.options = $.extend({}, $.fn.typeahead.defaults, options)
- this.matcher = this.options.matcher || this.matcher
- this.sorter = this.options.sorter || this.sorter
- this.highlighter = this.options.highlighter || this.highlighter
- this.$menu = $(this.options.menu).appendTo('body')
- this.source = this.options.source
- this.shown = false
- this.listen()
- }
-
- Typeahead.prototype = {
-
- constructor: Typeahead
-
- , select: function () {
- var val = this.$menu.find('.active').attr('data-value')
- this.$element.val(val)
- return this.hide()
- }
-
- , show: function () {
- var pos = $.extend({}, this.$element.offset(), {
- height: this.$element[0].offsetHeight
- })
-
- this.$menu.css({
- top: pos.top + pos.height
- , left: pos.left
- })
-
- this.$menu.show()
- this.shown = true
- return this
- }
-
- , hide: function () {
- this.$menu.hide()
- this.shown = false
- return this
- }
-
- , lookup: function (event) {
- var that = this
- , items
- , q
-
- this.query = this.$element.val()
-
- if (!this.query) {
- return this.shown ? this.hide() : this
- }
-
- items = $.grep(this.source, function (item) {
- if (that.matcher(item)) return item
- })
-
- items = this.sorter(items)
-
- if (!items.length) {
- return this.shown ? this.hide() : this
- }
-
- return this.render(items.slice(0, this.options.items)).show()
- }
-
- , matcher: function (item) {
- return ~item.toLowerCase().indexOf(this.query.toLowerCase())
- }
-
- , sorter: function (items) {
- var beginswith = []
- , caseSensitive = []
- , caseInsensitive = []
- , item
-
- while (item = items.shift()) {
- if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
- else if (~item.indexOf(this.query)) caseSensitive.push(item)
- else caseInsensitive.push(item)
- }
-
- return beginswith.concat(caseSensitive, caseInsensitive)
- }
-
- , highlighter: function (item) {
- return item.replace(new RegExp('(' + this.query + ')', 'ig'), function ($1, match) {
- return '<strong>' + match + '</strong>'
- })
- }
-
- , render: function (items) {
- var that = this
-
- items = $(items).map(function (i, item) {
- i = $(that.options.item).attr('data-value', item)
- i.find('a').html(that.highlighter(item))
- return i[0]
- })
-
- items.first().addClass('active')
- this.$menu.html(items)
- return this
- }
-
- , next: function (event) {
- var active = this.$menu.find('.active').removeClass('active')
- , next = active.next()
-
- if (!next.length) {
- next = $(this.$menu.find('li')[0])
- }
-
- next.addClass('active')
- }
-
- , prev: function (event) {
- var active = this.$menu.find('.active').removeClass('active')
- , prev = active.prev()
-
- if (!prev.length) {
- prev = this.$menu.find('li').last()
- }
-
- prev.addClass('active')
- }
-
- , listen: function () {
- this.$element
- .on('blur', $.proxy(this.blur, this))
- .on('keypress', $.proxy(this.keypress, this))
- .on('keyup', $.proxy(this.keyup, this))
-
- if ($.browser.webkit || $.browser.msie) {
- this.$element.on('keydown', $.proxy(this.keypress, this))
- }
-
- this.$menu
- .on('click', $.proxy(this.click, this))
- .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
- }
-
- , keyup: function (e) {
- e.stopPropagation()
- e.preventDefault()
-
- switch(e.keyCode) {
- case 40: // down arrow
- case 38: // up arrow
- break
-
- case 9: // tab
- case 13: // enter
- if (!this.shown) return
- this.select()
- break
-
- case 27: // escape
- this.hide()
- break
-
- default:
- this.lookup()
- }
-
- }
-
- , keypress: function (e) {
- e.stopPropagation()
- if (!this.shown) return
-
- switch(e.keyCode) {
- case 9: // tab
- case 13: // enter
- case 27: // escape
- e.preventDefault()
- break
-
- case 38: // up arrow
- e.preventDefault()
- this.prev()
- break
-
- case 40: // down arrow
- e.preventDefault()
- this.next()
- break
- }
- }
-
- , blur: function (e) {
- var that = this
- e.stopPropagation()
- e.preventDefault()
- setTimeout(function () { that.hide() }, 150)
- }
-
- , click: function (e) {
- e.stopPropagation()
- e.preventDefault()
- this.select()
- }
-
- , mouseenter: function (e) {
- this.$menu.find('.active').removeClass('active')
- $(e.currentTarget).addClass('active')
- }
-
- }
-
-
- /* TYPEAHEAD PLUGIN DEFINITION
- * =========================== */
-
- $.fn.typeahead = function ( option ) {
- return this.each(function () {
- var $this = $(this)
- , data = $this.data('typeahead')
- , options = typeof option == 'object' && option
- if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- $.fn.typeahead.defaults = {
- source: []
- , items: 8
- , menu: '<ul class="typeahead dropdown-menu"></ul>'
- , item: '<li><a href="#"></a></li>'
- }
-
- $.fn.typeahead.Constructor = Typeahead
-
-
- /* TYPEAHEAD DATA-API
- * ================== */
-
- $(function () {
- $('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
- var $this = $(this)
- if ($this.data('typeahead')) return
- e.preventDefault()
- $this.typeahead($this.data())
- })
- })
-
-}( window.jQuery ); \ No newline at end of file
diff --git a/horizon/static/bootstrap/js/bootstrap.min.js b/horizon/static/bootstrap/js/bootstrap.min.js
deleted file mode 100644
index 97dc88e1..00000000
--- a/horizon/static/bootstrap/js/bootstrap.min.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(a){a(function(){"use strict",a.support.transition=function(){var b=document.body||document.documentElement,c=b.style,d=c.transition!==undefined||c.WebkitTransition!==undefined||c.MozTransition!==undefined||c.MsTransition!==undefined||c.OTransition!==undefined;return d&&{end:function(){var b="TransitionEnd";return a.browser.webkit?b="webkitTransitionEnd":a.browser.mozilla?b="transitionend":a.browser.opera&&(b="oTransitionEnd"),b}()}}()})}(window.jQuery),!function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype={constructor:c,close:function(b){function f(){e.trigger("closed").remove()}var c=a(this),d=c.attr("data-target"),e;d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),e=a(d),e.trigger("close"),b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.trigger("close").removeClass("in"),a.support.transition&&e.hasClass("fade")?e.on(a.support.transition.end,f):f()}},a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("alert");e||d.data("alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a(function(){a("body").on("click.alert.data-api",b,c.prototype.close)})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.button.defaults,c)};b.prototype={constructor:b,setState:function(a){var b="disabled",c=this.$element,d=c.data(),e=c.is("input")?"val":"html";a+="Text",d.resetText||c.data("resetText",c[e]()),c[e](d[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},toggle:function(){var a=this.$element.parent('[data-toggle="buttons-radio"]');a&&a.find(".active").removeClass("active"),this.$element.toggleClass("active")}},a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("button"),f=typeof c=="object"&&c;e||d.data("button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.defaults={loadingText:"loading..."},a.fn.button.Constructor=b,a(function(){a("body").on("click.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle")})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.carousel.defaults,c),this.options.slide&&this.slide(this.options.slide)};b.prototype={cycle:function(){return this.interval=setInterval(a.proxy(this.next,this),this.options.interval),this},to:function(b){var c=this.$element.find(".active"),d=c.parent().children(),e=d.index(c),f=this;if(b>d.length-1||b<0)return;return this.sliding?this.$element.one("slid",function(){f.to(b)}):e==b?this.pause().cycle():this.slide(b>e?"next":"prev",a(d[b]))},pause:function(){return clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(b,c){var d=this.$element.find(".active"),e=c||d[b](),f=this.interval,g=b=="next"?"left":"right",h=b=="next"?"first":"last",i=this;if(!e.length)return;return this.sliding=!0,f&&this.pause(),e=e.length?e:this.$element.find(".item")[h](),!a.support.transition&&this.$element.hasClass("slide")?(this.$element.trigger("slide"),d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")):(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),this.$element.trigger("slide"),this.$element.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)})),f&&this.cycle(),this}},a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("carousel"),f=typeof c=="object"&&c;e||d.data("carousel",e=new b(this,f)),typeof c=="number"?e.to(c):typeof c=="string"||(c=f.slide)?e[c]():e.cycle()})},a.fn.carousel.defaults={interval:5e3},a.fn.carousel.Constructor=b,a(function(){a("body").on("click.carousel.data-api","[data-slide]",function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=!e.data("modal")&&a.extend({},e.data(),c.data());e.carousel(f),b.preventDefault()})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.collapse.defaults,c),this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.prototype={constructor:b,dimension:function(){var a=this.$element.hasClass("width");return a?"width":"height"},show:function(){var b=this.dimension(),c=a.camelCase(["scroll",b].join("-")),d=this.$parent&&this.$parent.find(".in"),e;d&&d.length&&(e=d.data("collapse"),d.collapse("hide"),e||d.data("collapse",null)),this.$element[b](0),this.transition("addClass","show","shown"),this.$element[b](this.$element[0][c])},hide:function(){var a=this.dimension();this.reset(this.$element[a]()),this.transition("removeClass","hide","hidden"),this.$element[a](0)},reset:function(a){var b=this.dimension();this.$element.removeClass("collapse")[b](a||"auto")[0].offsetWidth,this.$element.addClass("collapse")},transition:function(b,c,d){var e=this,f=function(){c=="show"&&e.reset(),e.$element.trigger(d)};this.$element.trigger(c)[b]("in"),a.support.transition&&this.$element.hasClass("collapse")?this.$element.one(a.support.transition.end,f):f()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("collapse"),f=typeof c=="object"&&c;e||d.data("collapse",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.collapse.defaults={toggle:!0},a.fn.collapse.Constructor=b,a(function(){a("body").on("click.collapse.data-api","[data-toggle=collapse]",function(b){var c=a(this),d,e=c.attr("data-target")||b.preventDefault()||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),f=a(e).data("collapse")?"toggle":c.data();a(e).collapse(f)})})}(window.jQuery),!function(a){function d(){a(b).parent().removeClass("open")}"use strict";var b='[data-toggle="dropdown"]',c=function(b){var c=a(b).on("click.dropdown.data-api",this.toggle);a("html").on("click.dropdown.data-api",function(){c.parent().removeClass("open")})};c.prototype={constructor:c,toggle:function(b){var c=a(this),e=c.attr("data-target"),f,g;return e||(e=c.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,"")),f=a(e),f.length||(f=c.parent()),g=f.hasClass("open"),d(),!g&&f.toggleClass("open"),!1}},a.fn.dropdown=function(b){return this.each(function(){var d=a(this),e=d.data("dropdown");e||d.data("dropdown",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.dropdown.Constructor=c,a(function(){a("html").on("click.dropdown.data-api",d),a("body").on("click.dropdown.data-api",b,c.prototype.toggle)})}(window.jQuery),!function(a){function c(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),d.call(b)},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),d.call(b)})}function d(a){this.$element.hide().trigger("hidden"),e.call(this)}function e(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('<div class="modal-backdrop '+d+'" />').appendTo(document.body),this.options.backdrop!="static"&&this.$backdrop.click(a.proxy(this.hide,this)),e&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),e?this.$backdrop.one(a.support.transition.end,b):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,a.proxy(f,this)):f.call(this)):b&&b()}function f(){this.$backdrop.remove(),this.$backdrop=null}function g(){var b=this;this.isShown&&this.options.keyboard?a(document).on("keyup.dismiss.modal",function(a){a.which==27&&b.hide()}):this.isShown||a(document).off("keyup.dismiss.modal")}"use strict";var b=function(b,c){this.options=c,this.$element=a(b).delegate('[data-dismiss="modal"]',"click.dismiss.modal",a.proxy(this.hide,this))};b.prototype={constructor:b,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var b=this;if(this.isShown)return;a("body").addClass("modal-open"),this.isShown=!0,this.$element.trigger("show"),g.call(this),e.call(this,function(){var c=a.support.transition&&b.$element.hasClass("fade");!b.$element.parent().length&&b.$element.appendTo(document.body),b.$element.show(),c&&b.$element[0].offsetWidth,b.$element.addClass("in"),c?b.$element.one(a.support.transition.end,function(){b.$element.trigger("shown")}):b.$element.trigger("shown")})},hide:function(b){b&&b.preventDefault();if(!this.isShown)return;var e=this;this.isShown=!1,a("body").removeClass("modal-open"),g.call(this),this.$element.trigger("hide").removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?c.call(this):d.call(this)}},a.fn.modal=function(c){return this.each(function(){var d=a(this),e=d.data("modal"),f=a.extend({},a.fn.modal.defaults,d.data(),typeof c=="object"&&c);e||d.data("modal",e=new b(this,f)),typeof c=="string"?e[c]():f.show&&e.show()})},a.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},a.fn.modal.Constructor=b,a(function(){a("body").on("click.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("modal")?"toggle":a.extend({},e.data(),c.data());b.preventDefault(),e.modal(f)})})}(window.jQuery),!function(a){"use strict";var b=function(a,b){this.init("tooltip",a,b)};b.prototype={constructor:b,init:function(b,c,d){var e,f;this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.enabled=!0,this.options.trigger!="manual"&&(e=this.options.trigger=="hover"?"mouseenter":"focus",f=this.options.trigger=="hover"?"mouseleave":"blur",this.$element.on(e,this.options.selector,a.proxy(this.enter,this)),this.$element.on(f,this.options.selector,a.proxy(this.leave,this))),this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(b){return b=a.extend({},a.fn[this.type].defaults,b,this.$element.data()),b.delay&&typeof b.delay=="number"&&(b.delay={show:b.delay,hide:b.delay}),b},enter:function(b){var c=a(b.currentTarget)[this.type](this._options).data(this.type);!c.options.delay||!c.options.delay.show?c.show():(c.hoverState="in",setTimeout(function(){c.hoverState=="in"&&c.show()},c.options.delay.show))},leave:function(b){var c=a(b.currentTarget)[this.type](this._options).data(this.type);!c.options.delay||!c.options.delay.hide?c.hide():(c.hoverState="out",setTimeout(function(){c.hoverState=="out"&&c.hide()},c.options.delay.hide))},show:function(){var a,b,c,d,e,f,g;if(this.hasContent()&&this.enabled){a=this.tip(),this.setContent(),this.options.animation&&a.addClass("fade"),f=typeof this.options.placement=="function"?this.options.placement.call(this,a[0],this.$element[0]):this.options.placement,b=/in/.test(f),a.remove().css({top:0,left:0,display:"block"}).appendTo(b?this.$element:document.body),c=this.getPosition(b),d=a[0].offsetWidth,e=a[0].offsetHeight;switch(b?f.split(" ")[1]:f){case"bottom":g={top:c.top+c.height,left:c.left+c.width/2-d/2};break;case"top":g={top:c.top-e,left:c.left+c.width/2-d/2};break;case"left":g={top:c.top+c.height/2-e/2,left:c.left-d};break;case"right":g={top:c.top+c.height/2-e/2,left:c.left+c.width}}a.css(g).addClass(f).addClass("in")}},setContent:function(){var a=this.tip();a.find(".tooltip-inner").html(this.getTitle()),a.removeClass("fade in top bottom left right")},hide:function(){function d(){var b=setTimeout(function(){c.off(a.support.transition.end).remove()},500);c.one(a.support.transition.end,function(){clearTimeout(b),c.remove()})}var b=this,c=this.tip();c.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?d():c.remove()},fixTitle:function(){var a=this.$element;(a.attr("title")||typeof a.attr("data-original-title")!="string")&&a.attr("data-original-title",a.attr("title")||"").removeAttr("title")},hasContent:function(){return this.getTitle()},getPosition:function(b){return a.extend({},b?{top:0,left:0}:this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight})},getTitle:function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||(typeof c.title=="function"?c.title.call(b[0]):c.title),a=a.toString().replace(/(^\s*|\s*$)/,""),a},tip:function(){return this.$tip=this.$tip||a(this.options.template)},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(){this[this.tip().hasClass("in")?"hide":"show"]()}},a.fn.tooltip=function(c){return this.each(function(){var d=a(this),e=d.data("tooltip"),f=typeof c=="object"&&c;e||d.data("tooltip",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.tooltip.Constructor=b,a.fn.tooltip.defaults={animation:!0,delay:0,selector:!1,placement:"top",trigger:"hover",title:"",template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'}}(window.jQuery),!function(a){"use strict";var b=function(a,b){this.init("popover",a,b)};b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype,{constructor:b,setContent:function(){var b=this.tip(),c=this.getTitle(),d=this.getContent();b.find(".popover-title")[a.type(c)=="object"?"append":"html"](c),b.find(".popover-content > *")[a.type(d)=="object"?"append":"html"](d),b.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var a,b=this.$element,c=this.options;return a=b.attr("data-content")||(typeof c.content=="function"?c.content.call(b[0]):c.content),a=a.toString().replace(/(^\s*|\s*$)/,""),a},tip:function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip}}),a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("popover"),f=typeof c=="object"&&c;e||d.data("popover",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.popover.Constructor=b,a.fn.popover.defaults=a.extend({},a.fn.tooltip.defaults,{placement:"right",content:"",template:'<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'})}(window.jQuery),!function(a){function b(b,c){var d=a.proxy(this.process,this),e=a(b).is("body")?a(window):a(b),f;this.options=a.extend({},a.fn.scrollspy.defaults,c),this.$scrollElement=e.on("scroll.scroll.data-api",d),this.selector=(this.options.target||(f=a(b).attr("href"))&&f.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=a("body").on("click.scroll.data-api",this.selector,d),this.refresh(),this.process()}"use strict",b.prototype={constructor:b,refresh:function(){this.targets=this.$body.find(this.selector).map(function(){var b=a(this).attr("href");return/^#\w/.test(b)&&a(b).length?b:null}),this.offsets=a.map(this.targets,function(b){return a(b).position().top})},process:function(){var a=this.$scrollElement.scrollTop()+this.options.offset,b=this.offsets,c=this.targets,d=this.activeTarget,e;for(e=b.length;e--;)d!=c[e]&&a>=b[e]&&(!b[e+1]||a<=b[e+1])&&this.activate(c[e])},activate:function(a){var b;this.activeTarget=a,this.$body.find(this.selector).parent(".active").removeClass("active"),b=this.$body.find(this.selector+'[href="'+a+'"]').parent("li").addClass("active"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active")}},a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("scrollspy"),f=typeof c=="object"&&c;e||d.data("scrollspy",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.defaults={offset:10},a(function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(window.jQuery),!function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype={constructor:b,show:function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.attr("data-target"),e,f;d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,""));if(b.parent("li").hasClass("active"))return;e=c.find(".active a").last()[0],b.trigger({type:"show",relatedTarget:e}),f=a(d),this.activate(b.parent("li"),c),this.activate(f,f.parent(),function(){b.trigger({type:"shown",relatedTarget:e})})},activate:function(b,c,d){function g(){e.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),f?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var e=c.find("> .active"),f=d&&a.support.transition&&e.hasClass("fade");f?e.one(a.support.transition.end,g):g(),e.removeClass("in")}},a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("tab");e||d.data("tab",e=new b(this)),typeof c=="string"&&e[c]()})},a.fn.tab.Constructor=b,a(function(){a("body").on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.typeahead.defaults,c),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.$menu=a(this.options.menu).appendTo("body"),this.source=this.options.source,this.shown=!1,this.listen()};b.prototype={constructor:b,select:function(){var a=this.$menu.find(".active").attr("data-value");return this.$element.val(a),this.hide()},show:function(){var b=a.extend({},this.$element.offset(),{height:this.$element[0].offsetHeight});return this.$menu.css({top:b.top+b.height,left:b.left}),this.$menu.show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(b){var c=this,d,e;return this.query=this.$element.val(),this.query?(d=a.grep(this.source,function(a){if(c.matcher(a))return a}),d=this.sorter(d),d.length?this.render(d.slice(0,this.options.items)).show():this.shown?this.hide():this):this.shown?this.hide():this},matcher:function(a){return~a.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(a){var b=[],c=[],d=[],e;while(e=a.shift())e.toLowerCase().indexOf(this.query.toLowerCase())?~e.indexOf(this.query)?c.push(e):d.push(e):b.push(e);return b.concat(c,d)},highlighter:function(a){return a.replace(new RegExp("("+this.query+")","ig"),function(a,b){return"<strong>"+b+"</strong>"})},render:function(b){var c=this;return b=a(b).map(function(b,d){return b=a(c.options.item).attr("data-value",d),b.find("a").html(c.highlighter(d)),b[0]}),b.first().addClass("active"),this.$menu.html(b),this},next:function(b){var c=this.$menu.find(".active").removeClass("active"),d=c.next();d.length||(d=a(this.$menu.find("li")[0])),d.addClass("active")},prev:function(a){var b=this.$menu.find(".active").removeClass("active"),c=b.prev();c.length||(c=this.$menu.find("li").last()),c.addClass("active")},listen:function(){this.$element.on("blur",a.proxy(this.blur,this)).on("keypress",a.proxy(this.keypress,this)).on("keyup",a.proxy(this.keyup,this)),(a.browser.webkit||a.browser.msie)&&this.$element.on("keydown",a.proxy(this.keypress,this)),this.$menu.on("click",a.proxy(this.click,this)).on("mouseenter","li",a.proxy(this.mouseenter,this))},keyup:function(a){a.stopPropagation(),a.preventDefault();switch(a.keyCode){case 40:case 38:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:this.hide();break;default:this.lookup()}},keypress:function(a){a.stopPropagation();if(!this.shown)return;switch(a.keyCode){case 9:case 13:case 27:a.preventDefault();break;case 38:a.preventDefault(),this.prev();break;case 40:a.preventDefault(),this.next()}},blur:function(a){var b=this;a.stopPropagation(),a.preventDefault(),setTimeout(function(){b.hide()},150)},click:function(a){a.stopPropagation(),a.preventDefault(),this.select()},mouseenter:function(b){this.$menu.find(".active").removeClass("active"),a(b.currentTarget).addClass("active")}},a.fn.typeahead=function(c){return this.each(function(){var d=a(this),e=d.data("typeahead"),f=typeof c=="object"&&c;e||d.data("typeahead",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.typeahead.defaults={source:[],items:8,menu:'<ul class="typeahead dropdown-menu"></ul>',item:'<li><a href="#"></a></li>'},a.fn.typeahead.Constructor=b,a(function(){a("body").on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(b){var c=a(this);if(c.data("typeahead"))return;b.preventDefault(),c.typeahead(c.data())})})}(window.jQuery); \ No newline at end of file
diff --git a/horizon/static/horizon/js/horizon.communication.js b/horizon/static/horizon/js/horizon.communication.js
deleted file mode 100644
index f1116d1e..00000000
--- a/horizon/static/horizon/js/horizon.communication.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Queued ajax handling for Horizon.
- *
- * Note: The number of concurrent AJAX connections hanlded in the queue
- * can be configured by setting an "ajax_queue_limit" key in
- * HORIZON_CONFIG to the desired number (or None to disable queue
- * limiting).
- */
-horizon.ajax = {
- // This will be our jQuery queue container.
- _queue: [],
- _active: [],
- get_messages: function (request) {
- return request.getResponseHeader("X-Horizon-Messages");
- },
- // Function to add a new call to the queue.
- queue: function(opts) {
- var complete = opts.complete,
- active = horizon.ajax._active;
-
- opts.complete = function () {
- var index = $.inArray(request, active);
- if (index > -1) {
- active.splice(index, 1);
- }
- horizon.ajax.next();
- if (complete) {
- complete.apply(this, arguments);
- }
- };
-
- function request() {
- return $.ajax(opts);
- }
-
- // Queue the request
- horizon.ajax._queue.push(request);
-
- // Start up the queue handler in case it's stopped.
- horizon.ajax.next();
- },
- next: function () {
- var queue = horizon.ajax._queue,
- limit = horizon.conf.ajax.queue_limit,
- request;
- if (queue.length && (!limit || horizon.ajax._active.length < limit)) {
- request = queue.pop();
- horizon.ajax._active.push(request);
- return request();
- }
- }
-};
diff --git a/horizon/static/horizon/js/horizon.conf.js b/horizon/static/horizon/js/horizon.conf.js
deleted file mode 100644
index ea97f25a..00000000
--- a/horizon/static/horizon/js/horizon.conf.js
+++ /dev/null
@@ -1,31 +0,0 @@
-horizon.conf = {
- // Placeholders; updated by Django.
- debug: null, //
- static_url: null,
- ajax: {
- queue_limit: null
- },
-
- // Config options which may be overridden.
- spinner_options: {
- inline: {
- lines: 10,
- length: 5,
- width: 2,
- radius: 3,
- color: '#000',
- speed: 0.8,
- trail: 50,
- zIndex: 100
- },
- modal: {
- lines: 10,
- length: 15,
- width: 4,
- radius: 10,
- color: '#000',
- speed: 0.8,
- trail: 50
- }
- }
-};
diff --git a/horizon/static/horizon/js/horizon.cookies.js b/horizon/static/horizon/js/horizon.cookies.js
deleted file mode 100644
index 7a16837d..00000000
--- a/horizon/static/horizon/js/horizon.cookies.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Convenience functions for dealing with namespaced Horizon cookies. */
-horizon.cookies = {
- read: function (cookie_name) {
- // Read in a cookie which contains JSON, and return a parsed object.
- var cookie = $.cookie("horizon." + cookie_name);
- if (cookie === null) {
- return {};
- }
- return $.parseJSON(cookie);
- },
- write: function (cookie_name, data) {
- // Overwrites a cookie.
- $.cookie("horizon." + cookie_name, JSON.stringify(data), {path: "/"});
- },
- update: function (cookie_name, key, value) {
- var data = horizon.cookies.read("horizon." + cookie_name);
- data[key] = value;
- horizon.cookies.write(cookie_name, data);
- },
- remove: function (cookie_name) {
- $.cookie("horizon." + cookie_name, null);
- }
-};
diff --git a/horizon/static/horizon/js/horizon.d3piechart.js b/horizon/static/horizon/js/horizon.d3piechart.js
deleted file mode 100644
index 816bfd9f..00000000
--- a/horizon/static/horizon/js/horizon.d3piechart.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- Draw pie chart in d3.
-
- To use, a div is required with the class .d3_pie_chart
- and a data-used attribute in the div
- that stores the percentage to fill the chart
-
- Example:
- <div class="d3_pie_chart"
- data-used="{% widthratio current_val max_val 100 %}">
- </div>
-*/
-
-horizon.d3_pie_chart = {
- w: 100,
- h: 100,
- r: 45,
- bkgrnd: "#F2F2F2",
- frgrnd: "#006CCF",
- full: "#D0342B",
- nearlyfull: "orange",
-
- init: function() {
- var self = this;
-
- // Pie Charts
- var pie_chart_data = $(".d3_pie_chart");
- self.chart = d3.selectAll(".d3_pie_chart");
-
- for (var i = 0; i < pie_chart_data.length; i++) {
- used = parseInt(pie_chart_data[i].dataset.used);
- self.data = [{"percentage":used}, {"percentage":100 - used}];
- self.pieChart(i);
- }
- },
- // Draw a pie chart
- pieChart: function(i) {
- var self = this;
- var vis = d3.select(self.chart[0][i]).append("svg:svg")
- .attr("class", "chart")
- .attr("width", self.w)
- .attr("height", self.h)
- .style("background-color", "white")
- .append("g")
- .attr("transform", "translate(" + (self.r + 2) + "," + (self.r + 2) + ")")
-
- var arc = d3.svg.arc()
- .outerRadius(self.r)
- .innerRadius(0)
-
- var pie = d3.layout.pie()
- .sort(null)
- .value(function(d){ return d.percentage; })
-
- // Draw an empty pie chart
- var piechart = vis.selectAll(".arc")
- .data(pie([{"percentage":10}]))
- .enter()
- .append("path")
- .attr("class","arc")
- .attr("d", arc)
- .style("fill", function(d){
- if (self.data[0].percentage >= 100) {
- return self.full;
- } else if (self.data[0].percentage >= 80) {
- return self.nearlyfull;
- } else {
- return self.frgrnd;
- }
- })
- .style("stroke", "#CCCCCC")
- .style("stroke-width", 1)
- .each(function(d) {return self.current = d;})
-
- // Animate filling the pie chart
- animate = function(data) {
- var piechart = vis.selectAll(".arc")
- .data(pie(data))
- .enter()
- .append("path")
- .attr("class","arc")
- .attr("d", arc)
- .style("fill", self.bkgrnd)
- .style("stroke", "#CCCCCC")
- .style("stroke-width", 1)
- .each(function(d) {return self.current = d;})
- .transition()
- .duration(500)
- .attrTween("d", function(a) {
- var tween = d3.interpolate(self.current, a);
- self.current = tween(0);
- return function(t) { return arc(tween(t)); }
- })
- }
-
- animate(self.data)
- }
-}
-
-horizon.addInitFunction(function () {
- horizon.d3_pie_chart.init();
-});
diff --git a/horizon/static/horizon/js/horizon.forms.js b/horizon/static/horizon/js/horizon.forms.js
deleted file mode 100644
index a26f04f5..00000000
--- a/horizon/static/horizon/js/horizon.forms.js
+++ /dev/null
@@ -1,190 +0,0 @@
-/* Namespace for core functionality related to Forms. */
-horizon.forms = {
- handle_snapshot_source: function() {
- $("div.table_wrapper, #modal_wrapper").on("change", "select#id_snapshot_source", function(evt) {
- var $option = $(this).find("option:selected");
- var $form = $(this).closest('form');
- var $volName = $form.find('input#id_name');
- $volName.val($option.data("display_name"));
- var $volSize = $form.find('input#id_size');
- $volSize.val($option.data("size"));
- });
- },
-
- handle_image_source: function() {
- $("div.table_wrapper, #modal_wrapper").on("change", "select#id_image_source", function(evt) {
- var $option = $(this).find("option:selected");
- var $form = $(this).closest('form');
- var $volName = $form.find('input#id_name');
- $volName.val($option.data("name"));
- var $volSize = $form.find('input#id_size');
- $volSize.val($option.data("size"));
- });
- },
-
- datepicker: function() {
- var startDate = $('input#id_start').datepicker()
- .on('changeDate', function(ev) {
- if (ev.date.valueOf() > endDate.date.valueOf()) {
- var newDate = new Date(ev.date)
- newDate.setDate(newDate.getDate() + 1);
- endDate.setValue(newDate);
- $('input#id_end')[0].focus();
- }
- startDate.hide();
- }).data('datepicker');
-
- var endDate = $('input#id_end').datepicker({
- onRender: function(date) {
- return date.valueOf() < startDate.date.valueOf() ? 'disabled' : '';
- }
- }).on('changeDate', function(ev) {
- endDate.hide();
- }).data('datepicker');
- }
-};
-
-horizon.forms.bind_add_item_handlers = function (el) {
- var $selects = $(el).find('select[data-add-item-url]');
- $selects.each(function () {
- var $this = $(this);
- $button = $("<a href='" + $this.attr("data-add-item-url") + "' " +
- "data-add-to-field='" + $this.attr("id") + "' " +
- "class='btn ajax-add ajax-modal btn-inline'>+</a>");
- $this.after($button);
- });
-};
-
-horizon.forms.prevent_multiple_submission = function (el) {
- // Disable multiple submissions when launching a form.
- var $form = $(el).find("form");
- $form.submit(function () {
- var button = $(this).find('[type="submit"]');
- if (button.hasClass('btn-primary') && !button.hasClass('always-enabled')){
- $(this).submit(function () {
- return false;
- });
- button.removeClass('primary').addClass('disabled');
- button.attr('disabled', 'disabled');
- }
- return true;
- });
-};
-
-horizon.forms.init_examples = function (el) {
- var $el = $(el);
-
- // FIXME(gabriel): These should be moved into the forms themselves as help text, etc.
- // Generic examples.
- $el.find("#id_description").attr("placeholder", gettext("Additional information here..."));
-
- // Update/create image form.
- $el.find("#create_image_form input#id_copy_from").attr("placeholder", "http://example.com/image.iso");
-
- // Table search box.
- $el.find(".table_search input").attr("placeholder", gettext("Filter"));
-
- // Volume attachment form.
- $el.find("#attach_volume_form #id_device").attr("placeholder", "/dev/vdc");
-};
-
-horizon.addInitFunction(function () {
- horizon.forms.prevent_multiple_submission($('body'));
- horizon.modals.addModalInitFunction(horizon.forms.prevent_multiple_submission);
-
- horizon.forms.bind_add_item_handlers($("body"));
- horizon.modals.addModalInitFunction(horizon.forms.bind_add_item_handlers);
-
- horizon.forms.init_examples($("body"));
- horizon.modals.addModalInitFunction(horizon.forms.init_examples);
-
- horizon.forms.handle_snapshot_source();
- horizon.forms.handle_image_source();
- horizon.forms.datepicker();
-
- // Bind event handlers to confirm dangerous actions.
- $("body").on("click", "form button.btn-danger", function (evt) {
- horizon.datatables.confirm(this);
- evt.preventDefault();
- });
-
- /* Switchable Fields (See Horizon's Forms docs for more information) */
-
- // Bind handler for swapping labels on "switchable" fields.
- $(document).on("change", 'select.switchable', function (evt) {
- var $fieldset = $(evt.target).closest('fieldset'),
- $switchables = $fieldset.find('.switchable');
-
- $switchables.each(function (index, switchable) {
- var $switchable = $(switchable),
- slug = $switchable.data('slug'),
- visible = $switchable.is(':visible'),
- val = $switchable.val();
-
- $fieldset.find('.switched[data-switch-on*="' + slug + '"]').each(function(index, input){
- var $input = $(input),
- data = $input.data(slug + "-" + val);
-
- if (typeof data === "undefined" || !visible) {
- $input.closest('.form-field').hide();
- } else {
- $('label[for=' + $input.attr('id') + ']').html(data);
- $input.closest('.form-field').show();
- }
- });
- });
- });
-
- // Fire off the change event to trigger the proper initial values.
- $('select.switchable').trigger('change');
- // Queue up the for new modals, too.
- horizon.modals.addModalInitFunction(function (modal) {
- $(modal).find('select.switchable').trigger('change');
- });
-
- // Handle field toggles for the Create Volume source type field
- function update_volume_source_displayed_fields (field) {
- var $this = $(field),
- base_type = $this.val();
-
- $this.find("option").each(function () {
- if (this.value != base_type) {
- $("#id_" + this.value).closest(".control-group").hide();
- } else {
- $("#id_" + this.value).closest(".control-group").show();
- }
- });
- }
-
- $(document).on('change', '#id_volume_source_type', function (evt) {
- update_volume_source_displayed_fields(this);
- });
-
- $('#id_volume_source_type').change();
- horizon.modals.addModalInitFunction(function (modal) {
- $(modal).find("#id_volume_source_type").change();
- });
-
- /* Help tooltips */
-
- // Apply standard handler for everything but checkboxes.
- $(document).tooltip({
- selector: "div.form-field :input:not(:checkbox)",
- placement: function (tip, input) {
- // Position to the right unless this is a "split" for in which case put
- // the tooltip below so it doesn't block the next field.
- return $(input).closest("form[class*='split']").length ? "bottom" : 'right';
- },
- trigger: 'focus',
- title: function () {
- return $(this).closest('div.form-field').children('.help-block').text();
- }
- });
- // Hide the tooltip upon interaction with the field for select boxes.
- // We use mousedown and keydown since those "open" the select dropdown.
- $(document).on('mousedown keydown', '.form-field select', function (evt) {
- $(this).tooltip('hide');
- });
- // Hide the help text for js-capable browsers
- $('span.help-block').hide();
-});
diff --git a/horizon/static/horizon/js/horizon.heattop.js b/horizon/static/horizon/js/horizon.heattop.js
deleted file mode 100644
index baf9e72c..00000000
--- a/horizon/static/horizon/js/horizon.heattop.js
+++ /dev/null
@@ -1,275 +0,0 @@
-/**
- *
- * HeatTop JS Framework
- * Dependencies: jQuery 1.7.1 or later, d3 v3 or later
- * Date: June 2013
- * Description: JS Framework that subclasses the D3 Force Directed Graph library to create
- * Heat-specific objects and relationships with the purpose of displaying
- * Stacks, Resources, and related Properties in a Resource Topology Graph.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- not use this file except in compliance with the License. You may obtain
- a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- License for the specific language governing permissions and limitations
- under the License.
-*/
-
-var container = "#heat_resource_topology";
-
-if ($(container).length){
- var width = $(container).width(),
- height = 500,
- stack_id = $("#stack_id").data("stack_id"),
- ajax_url = '/project/stacks/get_d3_data/'+stack_id+'/',
- graph = $("#d3_data").data("d3_data"),
- force = d3.layout.force()
- .nodes(graph.nodes)
- .links([])
- .gravity(0.1)
- .charge(-2000)
- .linkDistance(100)
- .size([width, height])
- .on("tick",tick),
- svg = d3.select(container).append("svg")
- .attr("width", width)
- .attr("height", height),
- node = svg.selectAll(".node"),
- link = svg.selectAll(".link"),
- needs_update = false,
- nodes = force.nodes(),
- links = force.links();
-
- build_links();
- update();
-
-
- function update(){
- node = node.data(nodes, function(d){return d.name});
- link = link.data(links);
-
- var nodeEnter = node.enter().append("g")
- .attr("class", "node")
- .attr("node_name", function(d){ return d.name })
- .attr("node_id", function(d){ return d.instance })
- .call(force.drag);
-
- nodeEnter.append("image")
- .attr("xlink:href", function(d) { return d.image; })
- .attr("id", function(d){return "image_"+ d.name})
- .attr("x", function(d) { return d.image_x; })
- .attr("y", function(d) { return d.image_y; })
- .attr("width", function(d) { return d.image_size; })
- .attr("height", function(d) { return d.image_size; });
- node.exit().remove();
-
- link.enter().insert("svg:line", "g.node")
- .attr("class", "link")
- .style("stroke-width", function(d) { return Math.sqrt(d.value); });
- link.exit().remove();
- //Setup click action for all nodes
- node.on("mouseover", function(d) {
- $("#info_box").html(d.info_box);
- current_info = d.name;
- });
- node.on("mouseout", function(d) {
- $("#info_box").html('');
- });
-
- force.start();
- }
- function tick() {
- link.attr("x1", function(d) { return d.source.x; })
- .attr("y1", function(d) { return d.source.y; })
- .attr("x2", function(d) { return d.target.x; })
- .attr("y2", function(d) { return d.target.y; });
-
- node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
- }
-
- //Load initial Stack box
- $("#stack_box").html(graph.stack.info_box);
- //On Page load, set Action In Progress
- var in_progress = false;
- set_in_progress(graph.stack, node);
-
- //If status is In Progress, start AJAX polling
- var poll_time = 0;
- if (in_progress == true){poll_time = 3000;}
- else {poll_time = 30000;}
- ajax_poll(poll_time);
-
- function set_in_progress(stack, nodes) {
- if (stack.in_progress == true){in_progress = true;}
- for (var i=0;i<nodes.length;i++) {
- var d = nodes[i];
- if (d.in_progress == true){in_progress = true;return false;}
- }
- }
- function findNode(name) {
- for (var i=0;i<nodes.length;i++) {if (nodes[i].name === name){return nodes[i];}};
- };
-
- function findNodeIndex(name) {
- for (var i=0;i<nodes.length;i++) {if (nodes[i].name==name){return i;}};
- };
- function addNode (node) {
- nodes.push(node);
- needs_update = true;
- };
- function removeNode (name) {
- var i = 0;
- var n = findNode(name);
- while (i < links.length) {
- if ((links[i]['source'] == n)||(links[i]['target'] == n))
- {
- links.splice(i,1);
- }
- else i++;
- }
- nodes.splice(findNodeIndex(name),1);
- needs_update = true;
- };
- function remove_nodes(old_nodes, new_nodes){
- //Check for removed nodes
- for (var i=0;i<old_nodes.length;i++) {
- var remove_node = true;
- for (var j=0;j<new_nodes.length;j++) {
- if (old_nodes[i].name==new_nodes[j].name){
- remove_node = false;
- break;
- }
- }
- if (remove_node==true){
- removeNode(old_nodes[i].name);
- }
- }
- }
- function build_links(){
- for (var i=0;i<nodes.length;i++){
- build_node_links(nodes[i]);
- build_reverse_links(nodes[i]);
- }
- }
- function build_node_links(node){
- for (var j=0;j<node.required_by.length;j++){
- var push_link = true;
- var target_idx = '';
- var source_idx = findNodeIndex(node.name);
- //make sure target node exists
- try {
- target_idx = findNodeIndex(node.required_by[j]);
- } catch(err) {
- console.log(err);
- push_link =false;
- }
- //check for duplicates
- for (var lidx=0;lidx<links.length;lidx++) {
- if ((links[lidx]['source'] == source_idx)&&(links[lidx]['target'] == target_idx))
- {
- push_link=false;
- break;
- }
- }
-
- if (push_link==true && (source_idx && target_idx)){
- links.push({
- 'source':source_idx,
- 'target':target_idx,
- 'value':1
- });
- }
- }
- }
-
- function build_reverse_links(node){
- for (var i=0;i<nodes.length;i++){
- if(nodes[i].required_by){
- for (var j=0;j<nodes[i].required_by.length;j++){
- var dependency = nodes[i].required_by[j];
- //if new node is required by existing node, push new link
- if(node.name==dependency){
- links.push({
- 'source':findNodeIndex(nodes[i].name),
- 'target':findNodeIndex(node.name),
- 'value':1
- })
- }
- }
- }
- }
- }
-
- function ajax_poll(poll_time){
- setTimeout(function() {
- $.getJSON(ajax_url, function(json) {
- //update d3 data element
- $("#d3_data").attr("data-d3_data", JSON.stringify(json));
-
- //update stack
- $("#stack_box").html(json.stack.info_box);
- set_in_progress(json.stack, json.nodes);
- needs_update = false;
-
- //Check Remove nodes
- remove_nodes(nodes, json.nodes);
-
- //Check for updates and new nodes
- json.nodes.forEach(function(d){
- current_node = findNode(d.name);
- //Check if node already exists
- if (current_node) {
- //Node already exists, just update it
- current_node.status = d.status;
-
- //Status has changed, image should be updated
- if (current_node.image != d.image){
- current_node.image = d.image;
- var this_image = d3.select("#image_"+current_node.name);
- this_image
- .transition()
- .attr("x", function(d) { return d.image_x + 5; })
- .duration(100)
- .transition()
- .attr("x", function(d) { return d.image_x - 5; })
- .duration(100)
- .transition()
- .attr("x", function(d) { return d.image_x + 5; })
- .duration(100)
- .transition()
- .attr("x", function(d) { return d.image_x - 5; })
- .duration(100)
- .transition()
- .attr("xlink:href", d.image)
- .transition()
- .attr("x", function(d) { return d.image_x; })
- .duration(100)
- .ease("bounce")
- }
-
- //Status has changed, update info_box
- current_node.info_box = d.info_box;
-
- } else {
- addNode(d);
- build_links();
- }
- });
-
- //if any updates needed, do update now
- if (needs_update==true){
- update();
- }
- });
- //if no nodes still in progress, slow AJAX polling
- if (in_progress==false){poll_time = 30000;}
- else {poll_time = 3000;}
- ajax_poll(poll_time);
- }, poll_time);
- }
-} \ No newline at end of file
diff --git a/horizon/static/horizon/js/horizon.instances.js b/horizon/static/horizon/js/horizon.instances.js
deleted file mode 100644
index f23abc20..00000000
--- a/horizon/static/horizon/js/horizon.instances.js
+++ /dev/null
@@ -1,226 +0,0 @@
-horizon.instances = {
- user_decided_length: false,
- networks_selected: [],
- networks_available: [],
-
- getConsoleLog: function(via_user_submit) {
- var form_element = $("#tail_length"),
- data;
-
- if (!via_user_submit) {
- via_user_submit = false;
- }
-
- if(this.user_decided_length) {
- data = $(form_element).serialize();
- } else {
- data = "length=35";
- }
-
- $.ajax({
- url: $(form_element).attr('action'),
- data: data,
- method: 'get',
- success: function(response_body) {
- $('pre.logs').text(response_body);
- },
- error: function(response) {
- if(via_user_submit) {
- horizon.clearErrorMessages();
- horizon.alert('error', gettext('There was a problem communicating with the server, please try again.'));
- }
- }
- });
- },
-
- disable_launch_button: function() {
- var launch_button = "#instances__action_launch";
-
- $(launch_button).click(function(e) {
- if ($(launch_button).hasClass("disabled")) {
- e.preventDefault();
- e.stopPropagation();
- }
- });
- },
-
- /*
- * Gets the html select element associated with a given
- * network id for network_id.
- **/
- get_network_element: function(network_id) {
- return $('li > label[for^="id_network_' + network_id + '"]');
- },
-
- /*
- * Initializes an associative array of lists of the current
- * networks.
- **/
- init_network_list: function() {
- horizon.instances.networks_selected = [];
- horizon.instances.networks_available = [];
- $(this.get_network_element("")).each(function(){
- var $this = $(this);
- var $input = $this.children("input");
- var network_property = {
- name:$this.text().replace(/^\s+/,""),
- id:$input.attr("id"),
- value:$input.attr("value")
- };
- if($input.is(':checked')) {
- horizon.instances.networks_selected.push(network_property);
- } else {
- horizon.instances.networks_available.push(network_property);
- }
- });
- },
-
- /*
- * Generates the HTML structure for a network that will be displayed
- * as a list item in the network list.
- **/
- generate_network_element: function(name, id, value) {
- var $li = $('<li>');
- $li.attr('name', value).html(name + '<em class="network_id">(' + value + ')</em><a href="#" class="btn btn-primary"></a>');
- return $li;
- },
-
- /*
- * Generates the HTML structure for the Network List.
- **/
- generate_networklist_html: function() {
- var self = this;
- var updateForm = function() {
- var lists = $("#networkListId div.input li").attr('data-index',100);
- var active_networks = $("#selected_network > li").map(function(){
- return $(this).attr("name");
- });
- $("#networkListId div.input input:checkbox").removeAttr('checked');
- active_networks.each(function(index, value){
- $("#networkListId div.input input:checkbox[value=" + value + "]")
- .attr('checked','checked')
- .parents("li").attr('data-index',index);
- });
- $("#networkListId div.input ul").html(
- lists.sort(function(a,b){
- if( $(a).data("index") < $(b).data("index")) return -1;
- if( $(a).data("index") > $(b).data("index")) return 1;
- return 0;
- })
- );
- };
- $("#networkListSortContainer").show();
- $("#networkListIdContainer").hide();
- self.init_network_list();
- // Make sure we don't duplicate the networks in the list
- $("#available_network").empty();
- $.each(self.networks_available, function(index, value){
- $("#available_network").append(self.generate_network_element(value.name, value.id, value.value));
- });
- // Make sure we don't duplicate the networks in the list
- $("#selected_network").empty();
- $.each(self.networks_selected, function(index, value){
- $("#selected_network").append(self.generate_network_element(value.name, value.id, value.value));
- });
- // $(".networklist > li").click(function(){
- // $(this).toggleClass("ui-selected");
- // });
- $(".networklist > li > a.btn").click(function(e){
- var $this = $(this);
- e.preventDefault();
- e.stopPropagation();
- if($this.parents("ul#available_network").length > 0) {
- $this.parent().appendTo($("#selected_network"));
- } else if ($this.parents("ul#selected_network").length > 0) {
- $this.parent().appendTo($("#available_network"));
- }
- updateForm();
- });
- if ($("#networkListId > div.control-group.error").length > 0) {
- var errortext = $("#networkListId > div.control-group.error").find("span.help-inline").text();
- $("#selected_network_h4").before($('<div class="dynamic-error">').html(errortext));
- }
- $(".networklist").sortable({
- connectWith: "ul.networklist",
- placeholder: "ui-state-highlight",
- distance: 5,
- start:function(e,info){
- $("#selected_network").addClass("dragging");
- },
- stop:function(e,info){
- $("#selected_network").removeClass("dragging");
- updateForm();
- }
- }).disableSelection();
- },
-
- workflow_init: function(modal) {
- // Initialise the drag and drop network list
- horizon.instances.generate_networklist_html();
- }
-};
-
-horizon.addInitFunction(function () {
- $(document).on('submit', '#tail_length', function (evt) {
- horizon.instances.user_decided_length = true;
- horizon.instances.getConsoleLog(true);
- evt.preventDefault();
- });
-
- // Disable the launch button if required
- horizon.instances.disable_launch_button();
-
- /* Launch instance workflow */
-
- // Handle field toggles for the Launch Instance source type field
- function update_launch_source_displayed_fields (field) {
- var $this = $(field),
- base_type = $this.val();
-
- $this.find("option").each(function () {
- if (this.value != base_type) {
- $("#id_" + this.value).closest(".control-group").hide();
- } else {
- $("#id_" + this.value).closest(".control-group").show();
- }
- });
- }
-
- $(document).on('change', '.workflow #id_source_type', function (evt) {
- update_launch_source_displayed_fields(this);
- });
-
- $('.workflow #id_source_type').change();
- horizon.modals.addModalInitFunction(function (modal) {
- $(modal).find("#id_source_type").change();
- });
-
- // Handle field toggles for the Launch Instance volume type field
- function update_launch_volume_displayed_fields (field) {
- var $this = $(field),
- volume_opt = $this.val(),
- $extra_fields = $("#id_delete_on_terminate, #id_device_name");
-
- $this.find("option").each(function () {
- if (this.value != volume_opt) {
- $("#id_" + this.value).closest(".control-group").hide();
- } else {
- $("#id_" + this.value).closest(".control-group").show();
- }
- });
-
- if (volume_opt === "volume_id" || volume_opt === "volume_snapshot_id") {
- $extra_fields.closest(".control-group").show();
- } else {
- $extra_fields.closest(".control-group").hide();
- }
- }
- $(document).on('change', '.workflow #id_volume_type', function (evt) {
- update_launch_volume_displayed_fields(this);
- });
-
- $('.workflow #id_volume_type').change();
- horizon.modals.addModalInitFunction(function (modal) {
- $(modal).find("#id_volume_type").change();
- });
-});
diff --git a/horizon/static/horizon/js/horizon.js b/horizon/static/horizon/js/horizon.js
deleted file mode 100644
index 5e7806e8..00000000
--- a/horizon/static/horizon/js/horizon.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/* This is the base Horizon JavaScript object. There is only ever one of these
- * loaded (referenced as horizon with a lower-case h) which happens immediately
- * after the definition below.
- *
- * Scripts that are dependent on functionality defined in the Horizon object
- * must be included after this script in templates/base.html.
- */
-var Horizon = function () {
- var horizon = {},
- initFunctions = [];
-
- /* Use the addInitFunction() function to add initialization code which must
- * be called on DOM ready. This is useful for adding things like event
- * handlers or any other initialization functions which should preceed user
- * interaction but rely on DOM readiness.
- */
- horizon.addInitFunction = function (fn) {
- initFunctions.push(fn);
- };
-
- /* Call all initialization functions and clear the queue. */
- horizon.init = function () {
- for (var i = 0; i < initFunctions.length; i += 1) {
- initFunctions[i]();
- }
-
- // Prevent multiple executions, just in case.
- initFunctions = [];
- };
-
- return horizon;
-};
-
-// Create the one and only horizon object.
-var horizon = new Horizon();
diff --git a/horizon/static/horizon/js/horizon.messages.js b/horizon/static/horizon/js/horizon.messages.js
deleted file mode 100644
index 7e924321..00000000
--- a/horizon/static/horizon/js/horizon.messages.js
+++ /dev/null
@@ -1,65 +0,0 @@
-horizon.alert = function (type, message, extra_tags) {
- safe = false
- // Check if the message is tagged as safe.
- if (typeof(extra_tags) !== "undefined" && _.contains(extra_tags.split(' '), 'safe')) {
- safe = true
- }
- var template = horizon.templates.compiled_templates["#alert_message_template"],
- params = {
- "type": type,
- "type_capitalized": horizon.utils.capitalize(type),
- "message": message,
- "safe": safe
- };
- return $(template.render(params)).hide().prependTo("#main_content .messages").fadeIn(100);
-};
-
-horizon.clearErrorMessages = function() {
- $('#main_content .messages .alert.alert-error').remove();
-};
-
-horizon.clearSuccessMessages = function() {
- $('#main_content .messages .alert.alert-success').remove();
-};
-
-horizon.clearAllMessages = function() {
- horizon.clearErrorMessages();
- horizon.clearSuccessMessages();
-};
-
-horizon.autoDismissAlerts = function() {
- var $alerts = $('#main_content .messages .alert');
-
- $alerts.each(function(index, alert) {
- var $alert = $(this),
- types = $alert.attr('class').split(' ');
-
- // Check if alert should auto-fade
- if (_.intersection(types, horizon.conf.auto_fade_alerts.types).length > 0) {
- setTimeout(function() {
- $alert.fadeOut(horizon.conf.auto_fade_alerts.fade_duration);
- }, horizon.conf.auto_fade_alerts.delay);
- }
- });
-}
-
-horizon.addInitFunction(function () {
- // Bind AJAX message handling.
- $("body").ajaxComplete(function(event, request, settings){
- var message_array = $.parseJSON(horizon.ajax.get_messages(request));
- $(message_array).each(function (index, item) {
- horizon.alert(item[0], item[1], item[2]);
- });
- });
-
- // Dismiss alert messages when moving on to a new type of action.
- $('a.ajax-modal').click(function() {
- horizon.clearAllMessages();
- });
-
- // Bind dismiss(x) handlers for alert messages.
- $(".alert").alert();
-
- // Hide alerts automatically if attribute data-dismiss-auto is set to true.
- horizon.autoDismissAlerts();
-});
diff --git a/horizon/static/horizon/js/horizon.modals.js b/horizon/static/horizon/js/horizon.modals.js
deleted file mode 100644
index 4034f8ed..00000000
--- a/horizon/static/horizon/js/horizon.modals.js
+++ /dev/null
@@ -1,223 +0,0 @@
-/* Namespace for core functionality related to modal dialogs.
- *
- * Modals in Horizon are treated as a "stack", e.g new ones are added to the
- * top of the stack, and they are always removed in a last-in-first-out
- * order. This allows for things like swapping between modals as part of a
- * workflow, for confirmations, etc.
- *
- * When a new modal is loaded into the DOM, it fires a "new_modal" event which
- * event handlers can listen for. However, for consistency, it is better to
- * add methods which should be run on instantiation of any new modal to be
- * applied via the horizon.modals.addModalInitFunction method.
- */
-horizon.modals = {
- // Storage for our current jqXHR object.
- _request: null,
- spinner: null,
- _init_functions: []
-};
-
-horizon.modals.addModalInitFunction = function (f) {
- horizon.modals._init_functions.push(f);
-};
-
-horizon.modals.initModal = function (modal) {
- $(horizon.modals._init_functions).each(function (index, f) {
- f(modal);
- });
-};
-
-/* Creates a modal dialog from the client-side template. */
-horizon.modals.create = function (title, body, confirm, cancel) {
- if (!cancel) {
- cancel = "Cancel";
- }
- var template = horizon.templates.compiled_templates["#modal_template"],
- params = {title: title, body: body, confirm: confirm, cancel: cancel},
- modal = $(template.render(params)).appendTo("#modal_wrapper");
- return modal;
-};
-
-horizon.modals.success = function (data, textStatus, jqXHR) {
- var modal;
- $('#modal_wrapper').append(data);
- $('.modal span.help-block').hide();
- modal = $('.modal:last');
- modal.modal();
- $(modal).trigger("new_modal", modal);
- return modal;
-};
-
-horizon.modals.modal_spinner = function (text) {
- // Adds a spinner with the desired text in a modal window.
- var template = horizon.templates.compiled_templates["#spinner-modal"];
- horizon.modals.spinner = $(template.render({text: text}));
- horizon.modals.spinner.appendTo("#modal_wrapper");
- horizon.modals.spinner.modal({backdrop: 'static'});
- horizon.modals.spinner.spin(horizon.conf.spinner_options.modal);
-};
-
-horizon.addInitFunction(function() {
- // Bind handler for initializing new modals.
- $('#modal_wrapper').on('new_modal', function (evt, modal) {
- horizon.modals.initModal(modal);
- });
-
- // Bind "cancel" button handler.
- $(document).on('click', '.modal .cancel', function (evt) {
- $(this).closest('.modal').modal('hide');
- evt.preventDefault();
- });
-
- // AJAX form submissions from modals. Makes validation happen in-modal.
- $(document).on('submit', '.modal form', function (evt) {
- var $form = $(this),
- $button = $form.find(".modal-footer .btn-primary"),
- update_field_id = $form.attr("data-add-to-field"),
- headers = {};
- if ($form.attr("enctype") === "multipart/form-data") {
- // AJAX-upload for files is not currently supported.
- return;
- }
- evt.preventDefault();
-
- // Prevent duplicate form POSTs
- $button.prop("disabled", true);
-
- if (update_field_id) {
- headers["X-Horizon-Add-To-Field"] = update_field_id;
- }
-
- $.ajax({
- type: "POST",
- url: $form.attr('action'),
- headers: headers,
- data: $form.serialize(),
- beforeSend: function () {
- $("#modal_wrapper .modal").last().modal("hide");
- horizon.modals.modal_spinner("Working");
- },
- complete: function () {
- horizon.modals.spinner.modal('hide');
- $("#modal_wrapper .modal").last().modal("show");
- $button.prop("disabled", false);
- },
- success: function (data, textStatus, jqXHR) {
- var redirect_header = jqXHR.getResponseHeader("X-Horizon-Location"),
- add_to_field_header = jqXHR.getResponseHeader("X-Horizon-Add-To-Field"),
- json_data, field_to_update;
- $form.closest(".modal").modal("hide");
- if (redirect_header) {
- location.href = redirect_header;
- }
- else if (add_to_field_header) {
- json_data = $.parseJSON(data);
- field_to_update = $("#" + add_to_field_header);
- field_to_update.append("<option value='" + json_data[0] + "'>" + json_data[1] + "</option>");
- field_to_update.change();
- field_to_update.val(json_data[0]);
- } else {
- horizon.modals.success(data, textStatus, jqXHR);
- }
- },
- error: function (jqXHR, status, errorThrown) {
- $form.closest(".modal").modal("hide");
- horizon.alert("error", gettext("There was an error submitting the form. Please try again."));
- }
- });
- });
-
- // Position modal so it's in-view even when scrolled down.
- $(document).on('show', '.modal', function (evt) {
- // Filter out indirect triggers of "show" from (for example) tabs.
- if ($(evt.target).hasClass("modal")) {
- var scrollShift = $('body').scrollTop(),
- $this = $(this),
- topVal = $this.css('top');
- $this.css('top', scrollShift + parseInt(topVal, 10));
- }
- });
-
- // Focus the first usable form field in the modal for accessibility.
- horizon.modals.addModalInitFunction(function (modal) {
- $(modal).find(":text, select, textarea").filter(":visible:first").focus();
- });
-
- horizon.modals.addModalInitFunction(horizon.datatables.validate_button);
-
- // Load modals for ajax-modal links.
- $(document).on('click', '.ajax-modal', function (evt) {
- var $this = $(this);
-
- // If there's an existing modal request open, cancel it out.
- if (horizon.modals._request && typeof(horizon.modals._request.abort) !== undefined) {
- horizon.modals._request.abort();
- }
-
- horizon.modals._request = $.ajax($this.attr('href'), {
- beforeSend: function () {
- horizon.modals.modal_spinner(gettext("Loading"));
- },
- complete: function () {
- // Clear the global storage;
- horizon.modals._request = null;
- horizon.modals.spinner.modal('hide');
- },
- error: function(jqXHR, status, errorThrown) {
- if (jqXHR.status === 401){
- var redir_url = jqXHR.getResponseHeader("X-Horizon-Location");
- if (redir_url){
- location.href = redir_url;
- } else {
- location.reload(true);
- }
- }
- else {
- if (!horizon.ajax.get_messages(jqXHR)) {
- // Generic error handler. Really generic.
- horizon.alert("error", gettext("An error occurred. Please try again later."));
- }
- }
- },
- success: function (data, textStatus, jqXHR) {
- var update_field_id = $this.attr('data-add-to-field'),
- modal, form;
- modal = horizon.modals.success(data, textStatus, jqXHR);
- if (update_field_id) {
- form = modal.find("form");
- if (form.length) {
- form.attr("data-add-to-field", update_field_id);
- }
- }
- }
- });
- evt.preventDefault();
- });
-
-
- /* Manage the modal "stack" */
-
- // When a new modal is opened, hide any that are already in the stack.
- $(document).on("show", ".modal", function () {
- var container = $("#modal_wrapper"),
- modal_stack = container.find(".modal"),
- $this = $(this);
- modal_stack.splice(modal_stack.length - 1, 1);
- modal_stack.modal("hide");
- });
-
- // After a modal has been fully hidden, remove it to avoid confusion.
- // Note: the modal should only be removed if it is the "top" of the stack of
- // modals, e.g. it's the one currently being interacted with and isn't just
- // temporarily being hidden.
- $(document).on('hidden', '.modal', function () {
- var $this = $(this),
- modal_stack = $("#modal_wrapper .modal");
- if ($this[0] == modal_stack.last()[0] || $this.hasClass("loading")) {
- $this.remove();
- if (!$this.hasClass("loading")) {
- $("#modal_wrapper .modal").last().modal("show");
- }
- }
- });
-});
diff --git a/horizon/static/horizon/js/horizon.networktopology.js b/horizon/static/horizon/js/horizon.networktopology.js
deleted file mode 100644
index dd4bd7e2..00000000
--- a/horizon/static/horizon/js/horizon.networktopology.js
+++ /dev/null
@@ -1,280 +0,0 @@
-/* Namespace for core functionality related to Network Topology. */
-horizon.network_topology = {
- model: null,
- network_margin: 270,
- topologyCanvas_padding: 120,
- min_network_height:500,
- port_margin: 20,
- device_initial_position : 40,
- device_last_position : 0,
- device_left_position : 90,
- device_margin : 20,
- device_min_height : 45,
- port_initial_position: 1,
- network_index: {},
- network_color_unit: 0,
- network_saturation: 1,
- network_lightness: 0.7,
- reload_duration: 10000,
- spinner:null,
- init:function(){
- var self = this;
- $("#topologyCanvas").spin(horizon.conf.spinner_options.modal);
- self.retrieve_network_info();
- setInterval(function(){
- self.retrieve_network_info();
- }, self.reload_duration);
- },
- retrieve_network_info: function(){
- var self = this;
- if($("#networktopology").length === 0) {
- return;
- }
- $.getJSON($("#networktopology").data("networktopology"),
- function(data) {
- self.draw_graph(data);
- }
- );
- },
- draw_loading: function () {
- $("#topologyCanvas").spin(horizon.conf.spinner_options.modal);
- },
- draw_graph: function(data){
- var canvas = $("#topologyCanvas");
- var networks = $("#topologyCanvas > .networks");
- var nodata = $("#topologyCanvas > .nodata");
- networks.show();
- nodata.hide();
- canvas.spin(false);
- networks.empty();
- this.model = data;
- this.device_last_position = this.device_initial_position;
- var network_elements = this.draw_networks();
- var router_elements = this.draw_routers();
- var server_elements = this.draw_servers();
- if ((network_elements + router_elements + server_elements) <= 0){
- networks.hide();
- nodata.show();
- } else {
- canvas.height(
- Math.max(this.device_last_position + this.topologyCanvas_padding, this.min_network_height)
- );
- networks.width(
- this.model.networks.length * this.network_margin
- );
- }
- },
- network_color: function(network_id){
- var max_hue = 360;
- var num_network = this.model.networks.length;
- if(num_network <= 0){
- return;
- }
- num_network ++;
- var hue = Math.floor(
- max_hue/num_network*(this.network_index(network_id) + 1));
- return this.hsv2rgb(
- hue, this.network_saturation, this.network_lightness);
- },
- //see http://en.wikipedia.org/wiki/HSL_and_HSV
- hsv2rgb:function (h, s, v) {
- var hi = Math.round(h/60) % 6;
- var f = h/60 - hi;
- var p = v*(1 - s);
- var q = v*(1 - f*s);
- var t = v*(1 - (1 - f)*s);
- switch(hi){
- case 0:
- r = v;
- g = t;
- b = p;
- break;
- case 1:
- r = q;
- g = v;
- b = p;
- break;
- case 2:
- r = p;
- g = v;
- b = t;
- break;
- case 3:
- r = p;
- g = q;
- b = v;
- break;
- case 4:
- r = t;
- g = p;
- b = v;
- break;
- case 5:
- r = v;
- g = p;
- b = q;
- break;
- }
- return "rgb(" + Math.round(r*255) + "," + Math.round(g*255) + "," + Math.round(b*255) + ")";
- },
- draw_networks: function(){
- var self = this;
- var networks = $("#topologyCanvas > .networks");
- $.each(self.model.networks, function(index, network){
- var label = (network.name != "")? network.name : network.id;
- if(network['router:external']){
- label += " (external) ";
- }
- self.network_index[network.id] = index;
- var network_html = $("<div class='network' />").attr("id", network.id);
- var nicname_html = $("<div class='nicname'><h3>" + label +
- "</h3><span class='ip'>" + self.select_cidr(network.id) + "</span></div>");
- if (network.url == undefined) {
- nicname_html.addClass("nourl");
- } else {
- nicname_html.click(function (){
- window.location.href = network.url;
- });
- }
- nicname_html
- .css (
- {'background-color':self.network_color(network.id)})
- .appendTo(network_html);
- networks.append(network_html);
- });
- return self.model.networks.length;
- },
- select_cidr:function(network_id){
- var cidr = [];
- $.each(this.model.subnets, function(index, subnet){
- if(subnet.network_id != network_id){
- return;
- }
- cidr.push(subnet.cidr);
- });
- return cidr.join(', ');
- },
- draw_devices: function(type){
- var self = this;
- $.each(self.model[type + 's'], function(index, device){
- var id = device.id;
- var name = (device.name != "")? device.name : device.id;
- var ports = self.select_port(id);
- if(ports.length <= 0){
- return;
- }
- var main_port = self.select_main_port(ports);
- var parent_network = main_port.network_id;
- var device_html = $("<div class='" + type + "'></div>");
- device_html
- .attr('id', device.id)
- .css({top: self.device_last_position, position: 'absolute'})
- .append($("<span class='devicename'><i></i>" + type + "</span>"))
- .click(function (e){
- e.stopPropagation();
- window.location.href = device.url;
- });
- var name_html = $("<span class='name'></span>")
- .html(device.name)
- .attr('title', device.name)
- .appendTo(device_html);
- var port_position = self.port_initial_position;
- $.each(ports, function(){
- var port = this;
- var port_html = self.port_html(port);
- port_position += self.port_margin;
- self.port_css(port_html, port_position, parent_network, port.network_id);
- device_html.append(port_html);
- });
- port_position += self.port_margin;
- device_html.css(
- {height: Math.max(self.device_min_height, port_position) + "px"});
- self.device_last_position += device_html.height() + self.device_margin;
- $("#" + parent_network).append(device_html);
- $('div.port span.ip').each(function(i, ip){
- $(ip).css('top', '-'+$(ip).height()+'px');
- });
- });
- return self.model[type + 's'].length;
- },
- sum_port_length: function(network_id, ports){
- var self = this;
- var sum_port_length = 0;
- var base_index = self.network_index(network_id);
- $.each(ports, function(index, port){
- sum_port_length += base_index - self.network_index(port.network_id);
- });
- return sum_port_length;
- },
- select_main_port: function(ports){
- var main_port_index = 0;
- var MAX_INT = 4294967295;
- var min_port_length = MAX_INT;
- $.each(ports, function(index, port){
- port_length = horizon.network_topology.sum_port_length(port.network_id, ports)
- if(port_length < min_port_length){
- min_port_length = port_length;
- main_port_index = index;
- }
- })
- return ports[main_port_index];
- },
- draw_routers: function(){
- return this.draw_devices('router');
- },
- draw_servers: function(){
- return this.draw_devices('server');
- },
- select_port: function(device_id){
- return $.map(this.model.ports,function(port, index){
- if (port.device_id == device_id) {
- return port;
- }
- });
- },
- port_html: function(port){
- var self = this;
- var port_html = $('<div class="port"><div class="dot"></div></div>');
- var ip_label = "";
- $.each(port.fixed_ips, function(){
- ip_label += this.ip_address + "<br />";
- })
- var ip_html = $('<span class="ip" />').html(ip_label);
- port_html
- .append(ip_html)
- .css({'background-color':self.network_color(port.network_id)})
- .click(function (e) {
- e.stopPropagation();
- if(port.url != undefined) {
- window.location.href = port.url;
- }
- });
- if(port.url == undefined) {
- port_html.addClass("nourl");
- }
- return port_html;
- },
- port_css: function(port_html, position, network_a, network_b){
- var self = this;
- var index_diff = self.network_index(network_a) - self.network_index(network_b);
- var width = self.network_margin * index_diff;
- var direction = "left";
- if(width < 0){
- direction = "right";
- width += self.network_margin;
- }
- width = Math.abs(width) + self.device_left_position;
- var port_css = {};
- port_css['width'] = width + "px";
- port_css['top'] = position + "px";
- port_css[direction] = (-width -3) + "px";
- port_html.addClass(direction).css(port_css);
- },
- network_index: function(network_id){
- return horizon.network_topology.network_index[network_id];
- }
-}
-
-horizon.addInitFunction(function () {
- horizon.network_topology.init();
-});
diff --git a/horizon/static/horizon/js/horizon.projects.js b/horizon/static/horizon/js/horizon.projects.js
deleted file mode 100644
index cb8efaa2..00000000
--- a/horizon/static/horizon/js/horizon.projects.js
+++ /dev/null
@@ -1,474 +0,0 @@
-/* Namespace for core functionality related to Project Workflows. */
-horizon.projects = {
-
- current_membership: [],
- users: [],
- roles: [],
- has_roles: true,
- default_role_id: "",
-
- /* Parses the form field selector's ID to get either the
- * role or user id (i.e. returns "id12345" when
- * passed the selector with id: "id_user_id12345").
- **/
- get_field_id: function(id_string) {
- return id_string.slice(id_string.lastIndexOf("_") + 1);
- },
-
- /*
- * Gets the html select element associated with a given
- * role id.
- **/
- get_role_element: function(role_id) {
- return $('select[id^="id_role_' + role_id + '"]');
- },
-
- /*
- * Gets the html ul element associated with a given
- * user id. I.e., the user's row.
- **/
- get_user_element: function(user_id) {
- return $('li[data-user-id$=' + user_id + ']').parent();
- },
-
- /*
- * Initializes all of the horizon.projects lists with
- * data parsed from the hidden form fields, as well as the
- * default role id.
- **/
- init_properties: function() {
- horizon.projects.has_roles = $(".project_membership").data('show-roles') !== "no";
- horizon.projects.default_role_id = $('#id_default_role').attr('value');
- horizon.projects.init_user_list();
- horizon.projects.init_role_list();
- horizon.projects.init_current_membership();
- },
-
- /*
- * Initializes an associative array mapping user ids to user names.
- **/
- init_user_list: function() {
- horizon.projects.users = [];
- _.each($(this.get_role_element("")).find("option"), function (option) {
- horizon.projects.users[option.value] = option.text;
- });
- },
-
- /*
- * Initializes an associative array mapping role ids to role names.
- **/
- init_role_list: function() {
- horizon.projects.roles = [];
- _.each($('label[for^="id_role_"]'), function(role) {
- var id = horizon.projects.get_field_id($(role).attr('for'));
- horizon.projects.roles[id] = $(role).text();
- });
- },
-
- /*
- * Initializes an associative array of lists of the current
- * members for each available role.
- **/
- init_current_membership: function() {
- horizon.projects.current_membership = [];
- var members_list = [];
- var role_name, role_id, selected_members;
- _.each(this.get_role_element(''), function(value, key) {
- role_id = horizon.projects.get_field_id($(value).attr('id'));
- role_name = $('label[for="id_role_' + role_id + '"]').text();
-
- // get the array of members who are selected in this list
- selected_members = $(value).find("option:selected");
- // extract the member names and add them to the dictionary of lists
- members_list = [];
- if (selected_members) {
- _.each(selected_members, function(member) {
- members_list.push(member.value);
- });
- }
- horizon.projects.current_membership[role_id] = members_list;
- });
- },
-
- /*
- * Returns the ids of roles the user is a member of.
- **/
- get_user_roles: function(user_id) {
- var roles = [];
- for (var role in horizon.projects.current_membership) {
- if ($.inArray(user_id, horizon.projects.current_membership[role]) >= 0) {
- roles.push(role);
- }
- }
- return roles;
- },
-
- /*
- * Updates the selected values on the role_list's form field, as
- * well as the current_membership dictionary's list.
- **/
- update_role_lists: function(role_id, new_list) {
- this.get_role_element(role_id).val(new_list);
- horizon.projects.current_membership[role_id] = new_list;
- },
-
- /*
- * Helper function for remove_user_from_role.
- **/
- remove_user: function(user_id, role_id, role_list) {
- var index = role_list.indexOf(user_id);
- if (index >= 0) {
- // remove member from list
- role_list.splice(index, 1);
- horizon.projects.update_role_lists(role_id, role_list);
- }
- },
-
- /*
- * Searches through the role lists and removes a given user
- * from the lists.
- **/
- remove_user_from_role: function(user_id, role_id) {
- var role_list;
- if (role_id) {
- role_list = horizon.projects.current_membership[role_id];
- horizon.projects.remove_user(user_id, role_id, role_list);
- }
- else {
- // search for membership in role lists
- for (var role in horizon.projects.current_membership) {
- role_list = horizon.projects.current_membership[role];
- horizon.projects.remove_user(user_id, role, role_list);
- }
- }
- },
-
- /*
- * Adds a given user to a given role list.
- **/
- add_user_to_role: function(user_id, role_id) {
- var role_list = horizon.projects.current_membership[role_id];
- role_list.push(user_id);
- horizon.projects.update_role_lists(role_id, role_list);
- },
-
- update_user_role_dropdown: function(user_id, role_ids, user_el) {
- if (typeof(role_ids) === 'undefined') {
- role_ids = horizon.projects.get_user_roles(user_id);
- }
- if (typeof(user_el) === 'undefined') {
- user_el = horizon.projects.get_user_element(user_id);
- }
-
- var $dropdown = user_el.find("li.member").siblings('.dropdown');
- var $role_items = $dropdown.children('.role_dropdown').children('li');
-
- $role_items.each(function (idx, el) {
- if (_.contains(role_ids, $(el).data('role-id'))) {
- $(el).addClass('selected');
- } else {
- $(el).removeClass('selected');
- }
- });
-
- // set the selection back to default role
- var $roles_display = $dropdown.children('.dropdown-toggle').children('.roles_display');
- var roles_to_display = [];
- for (var i = 0; i < role_ids.length; i++) {
- if (i == 2) {
- roles_to_display.push('...');
- break;
- }
- roles_to_display.push(horizon.projects.roles[role_ids[i]]);
- }
- text = roles_to_display.join(', ');
- if (text.length == 0) text = 'No roles';
- $roles_display.text(text);
- },
-
- /*
- * Generates the HTML structure for a user that will be displayed
- * as a list item in the project member list.
- **/
- generate_user_element: function(user_name, user_id, role_ids, text) {
- var str_id = "id_user_" + user_id;
-
- var roles = [];
- for (var r in horizon.projects.roles) {
- var role = {};
- role['role_id'] = r;
- role['role_name'] = horizon.projects.roles[r];
- roles.push(role);
- }
-
- var template = horizon.templates.compiled_templates["#project_user_template"],
- params = {user_id: str_id,
- default_role: horizon.projects.roles[horizon.projects.default_role_id],
- user_name: user_name,
- text: text,
- roles: roles},
- user_el = $(template.render(params));
- this.update_user_role_dropdown(str_id, role_ids, user_el);
- return $(user_el);
- },
-
- /*
- * Generates the HTML structure for the project membership UI.
- **/
- generate_html: function() {
- var user;
- for (user in horizon.projects.users) {
- var user_id = user;
- var user_name = horizon.projects.users[user];
- var role_ids = this.get_user_roles(user_id);
- if (role_ids.length > 0) {
- $(".project_members").append(this.generate_user_element(user_name, user_id, role_ids, "-"));
- }
- else {
- $(".available_users").append(this.generate_user_element(user_name, user_id, role_ids, "+"));
- }
- }
- horizon.projects.detect_no_results();
- },
-
- /*
- * Triggers on click of link to add/remove member from the project.
- **/
- update_membership: function() {
- $(".available_users, .project_members").on('click', ".btn-group a[href='#add_remove']", function (evt) {
- evt.preventDefault();
- var available = $(".available_users").has($(this)).length;
- var user_id = horizon.projects.get_field_id($(this).parent().siblings().attr('data-user-id'));
- var user_el = $(this).parent().parent();
-
- if (available) {
- var default_role = horizon.projects.default_role_id;
- $(this).text("-");
- $(".project_members").append(user_el);
- horizon.projects.add_user_to_role(user_id, default_role);
-
- if (horizon.projects.has_roles) {
- $(this).parent().siblings(".role_options").show();
- horizon.projects.update_user_role_dropdown(user_id, [default_role], user_el);
- }
- }
- else {
- $(this).text("+");
- $(this).parent().siblings(".role_options").hide();
- $(".available_users").append(user_el);
- horizon.projects.remove_user_from_role(user_id);
- }
-
- // update lists
- horizon.projects.list_filtering();
- horizon.projects.detect_no_results();
-
- // remove input filters
- $("input.filter").val("");
- });
- },
-
- /*
- * Detects whether each list has members and if it does not
- * displays a message to the user.
- **/
- detect_no_results: function () {
- $('.filterable').each( function () {
- var filter = $(this).find('ul').attr('class');
-
- if (!$('.' + filter).children('ul').length) {
- $('#no_' + filter).show();
- $("input[id='" + filter + "']").attr('disabled', 'disabled');
- }
- else {
- $('#no_' + filter).hide();
- $("input[id='" + filter + "']").removeAttr('disabled');
- }
- });
- },
-
- /*
- * Triggers on selection of new role for a member.
- **/
- select_member_role: function() {
- $(".available_users, .project_members").on('click', '.role_dropdown li', function (evt) {
- evt.preventDefault();
- evt.stopPropagation();
-
- // get the newly selected role and the member's name
- var new_role_id = $(this).attr("data-role-id");
- var id_str = $(this).parent().parent().siblings(".member").attr("data-user-id");
- var user_id = horizon.projects.get_field_id(id_str);
-
- // update role lists
- if ($(this).hasClass('selected')) {
- $(this).removeClass('selected');
- horizon.projects.remove_user_from_role(user_id, new_role_id);
- } else {
- $(this).addClass('selected');
- horizon.projects.add_user_to_role(user_id, new_role_id);
- }
- horizon.projects.update_user_role_dropdown(user_id);
- });
- },
-
- /*
- * Triggers on the addition of a new user via the inline object creation field.
- **/
- add_new_user: function() {
- $("select[id='id_new_user']").on('change', function (evt) {
- // add the user to the visible list
- var user_name = $(this).find("option").text();
- var user_id = $(this).find("option").attr("value");
- var default_role_id = horizon.projects.default_role_id;
- $(".project_members").append(horizon.projects.generate_user_element(user_name, user_id, [default_role_id], "-"));
-
- // add the user to the hidden role lists and the users list
- horizon.projects.users[user_id] = user_name;
- $("select[multiple='multiple']").append("<option value='" + user_id + "'>" + horizon.projects.users[user_id] + "</option>");
- horizon.projects.add_user_to_role(user_id, default_role_id);
-
- // remove option from hidden select
- $(this).text("");
-
- // reset lists and input filters
- horizon.projects.list_filtering();
- horizon.projects.detect_no_results();
- $("input.filter").val("");
-
- // fix styling
- $(".project_members .btn-group").removeClass('last_stripe');
- $(".project_members .btn-group:last").addClass('last_stripe');
- });
- },
-
- /*
- * Style the inline object creation button, hide the associated field.
- **/
- add_new_user_styling: function() {
- var add_user_el = $("label[for='id_new_user']").parent();
- $(add_user_el).find("select").hide();
- $("#add_user").append($(add_user_el));
- $(add_user_el).addClass("add_user");
- $(add_user_el).find("label, .input").addClass("add_user_btn");
- },
-
- /*
- * Fixes the striping of the fake table upon modification of the lists.
- **/
- fix_stripes: function() {
- $('.fake_table').each( function () {
- var filter = "." + $(this).attr('id');
- var visible = " .btn-group:visible";
- var even = " .btn-group:visible:even";
- var last = " .btn-group:visible:last";
-
- // fix striping of rows
- $(filter + visible).removeClass('dark_stripe');
- $(filter + visible).addClass('light_stripe');
- $(filter + even).removeClass('light_stripe');
- $(filter + even).addClass('dark_stripe');
-
- // fix bottom border of new last element
- $(filter + visible).removeClass('last_stripe');
- $(filter + last).addClass('last_stripe');
- });
- },
-
- /*
- * Sets up filtering for each list of users.
- **/
- list_filtering: function () {
- // remove previous lists' quicksearch events
- $('input.filter').unbind();
-
- // set up quicksearch to filter on input
- $('.filterable').each(function () {
- var filter = $(this).children().children('ul').attr('class');
- var input = $("input[id='" + filter +"']");
- input.quicksearch('ul.' + filter + ' ul li span.user_name', {
- 'delay': 200,
- 'loader': 'span.loading',
- 'show': function () {
- $(this).parent().parent().show();
- if (filter == "available_users") {
- $(this).parent('.dropdown-toggle').hide();
- }
- },
- 'hide': function () {
- $(this).parent().parent().hide();
- },
- 'noResults': 'ul#no_' + filter,
- 'onAfter': function () {
- horizon.projects.fix_stripes();
- },
- 'prepareQuery': function (val) {
- return new RegExp(val, "i");
- },
- 'testQuery': function (query, txt, span) {
- if ($(input).attr('id') == filter) {
- $(input).prev().removeAttr('disabled');
- return query.test($(span).text());
- }
- else
- return true;
- }
- });
- });
- },
-
- /*
- * Calls set-up functions upon loading the workflow.
- **/
- workflow_init: function(modal) {
- // fix the dropdown menu overflow issues
- $(".tab-content, .workflow").addClass("dropdown_fix");
-
- $(modal).find('form').each( function () {
- var $form = $(this);
-
- // Do nothing if this isn't a membership modal
- if ($form.find('div.project_membership').length == 0) {
- return; // continue
- }
-
- // call the initalization functions
- horizon.projects.init_properties();
- horizon.projects.generate_html();
- horizon.projects.update_membership();
- horizon.projects.select_member_role();
- horizon.projects.add_new_user();
-
- // initially hide role dropdowns for available users list
- $form.find(".available_users .role_options").hide();
-
- // hide the dropdown for members too if we don't need to show it
- if (!horizon.projects.has_roles) {
- $form.find(".project_members .role_options").hide();
- }
-
- // unfocus filter fields
- $form.find("#update_project__update_members input").blur();
-
- // prevent filter inputs from submitting form on 'enter'
- $form.find('.project_membership').keydown(function(event){
- if(event.keyCode == 13) {
- event.preventDefault();
- return false;
- }
- });
-
- // add filtering + styling to the inline obj creation btn
- horizon.projects.add_new_user_styling();
- horizon.projects.list_filtering();
- horizon.projects.detect_no_results();
-
- // fix initial striping of rows
- $form.find('.fake_table').each( function () {
- var filter = "." + $(this).attr('id');
- $(filter + ' .btn-group:even').addClass('dark_stripe');
- $(filter + ' .btn-group:last').addClass('last_stripe');
- });
- });
- }
-};
diff --git a/horizon/static/horizon/js/horizon.quota.js b/horizon/static/horizon/js/horizon.quota.js
deleted file mode 100644
index 7b78366b..00000000
--- a/horizon/static/horizon/js/horizon.quota.js
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- Used for animating and displaying quota information on forms using
- D3js progress bars. Also used for displaying flavor details on modal-
- dialogs.
-
- Usage:
- In order to have progress bars that work with this, you need to have a
- DOM structure like this in your Django template:
-
- <div id="your_progress_bar_id" class="quota_bar">
- </div>
-
- With this progress bar, you then need to add some data- HTML attributes
- to the div #your_progress_bar_id. The available data- attributes are:
-
- data-quota-used="integer" REQUIRED
- Integer representing the total number used by the user.
-
- data-quota-limit="integer" REQUIRED
- Integer representing the total quota limit the user has. Note this IS
- NOT the amount remaining they can use, but the total original quota.
-
- ONE OF THE THREE ATTRIBUTES BELOW IS REQUIRED:
-
- data-progress-indicator-step-by="integer" OPTIONAL
- Indicates the numeric unit the quota JavaScript should automatically
- animate this progress bar by on load. Can be used with the other
- data- attributes.
-
- A good use-case here is when you have a modal dialog to create ONE
- volume, and you have a progress bar for volumes, but there are no
- form elements that represent that number (as it is not settable by
- the user.)
-
- data-progress-indicator-for="html_id_of_form_input"
- Tells the quota JavaScript which form element on this page is tied to
- this progress indicator. If this form element is an input, it will
- automatically fire on "keyup" in that form field, and change this
- progress bar to denote the numeric change.
-
- data-progress-indicator-flavor
- This attribute is used to tell this quota JavaScript that this
- progress bar is controller by an instance flavor select form element.
- This attribute takes no value, but is used and configured
- automatically by this script to update when a new flavor is choosen
- by the end-user.
- */
-horizon.Quota = {
- is_flavor_quota: false, // Is this a flavor-based quota display?
- user_value_progress_bars: [], // Progress bars triggered by user-changeable form elements.
- auto_value_progress_bars: [], // Progress bars that should be automatically changed.
- flavor_progress_bars: [], // Progress bars that relate to flavor details.
- user_value_form_inputs: [], // The actual form inputs that trigger progress changes.
- selected_flavor: null, // The flavor object of the current selected flavor on the form.
- flavors: [], // The flavor objects the form represents, passed to us in initWithFlavors.
-
- /*
- Determines the progress bars and form elements to be used for quota
- display. Also attaches handlers to the form elements as well as performing
- the animations when the progress bars first load.
- */
- init: function() {
- this.user_value_progress_bars = $('div[data-progress-indicator-for]');
- this.auto_value_progress_bars = $('div[data-progress-indicator-step-by]');
- this.user_value_form_inputs = $($.map(this.user_value_progress_bars, function(elm) {
- return ('#' + $(elm).attr('data-progress-indicator-for'));
- }));
-
- // Draw the initial progress bars
- this._initialCreation(this.user_value_progress_bars)
- this._initialCreation(this.auto_value_progress_bars)
- this._initialCreation(this.flavor_progress_bars)
-
- this._initialAnimations();
- this._attachInputHandlers();
- },
-
- /*
- Sets up the quota to be used with flavor form selectors, which requires
- some different handling of the forms. Also calls init() so that all of the
- other animations and handlers are taken care of as well when initializing
- with this method.
- */
- initWithFlavors: function(flavors) {
- this.is_flavor_quota = true;
- this.flavor_progress_bars = $('div[data-progress-indicator-flavor]');
- this.flavors = flavors;
-
- this.init();
-
- this.showFlavorDetails();
- this.updateFlavorUsage();
- },
-
- // Returns the flavor object for the selected flavor in the form.
- getSelectedFlavor: function() {
- if(this.is_flavor_quota) {
- this.selected_flavor = _.find(this.flavors, function(flavor) {
- return flavor.id == $("#id_flavor").children(":selected").val();
- });
- } else {
- this.selected_flavor = null;
- }
-
- return this.selected_flavor;
- },
-
- /*
- Populates the flavor details table with the flavor attributes of the
- selected flavor on the form select element.
- */
- showFlavorDetails: function() {
- this.getSelectedFlavor();
-
- if (this.selected_flavor) {
- var name = horizon.utils.truncate(this.selected_flavor.name, 14, true);
- var vcpus = horizon.utils.humanizeNumbers(this.selected_flavor.vcpus);
- var disk = horizon.utils.humanizeNumbers(this.selected_flavor.disk);
- var ephemeral = horizon.utils.humanizeNumbers(this.selected_flavor["OS-FLV-EXT-DATA:ephemeral"]);
- var disk_total = this.selected_flavor.disk + this.selected_flavor["OS-FLV-EXT-DATA:ephemeral"];
- var disk_total_display = horizon.utils.humanizeNumbers(disk_total);
- var ram = horizon.utils.humanizeNumbers(this.selected_flavor.ram);
-
- $("#flavor_name").html(name);
- $("#flavor_vcpus").text(vcpus);
- $("#flavor_disk").text(disk);
- $("#flavor_ephemeral").text(ephemeral);
- $("#flavor_disk_total").text(disk_total_display);
- $("#flavor_ram").text(ram);
- }
- },
-
- /*
- When a new flavor is selected, this takes care of updating the relevant
- progress bars associated with the flavor quota usage.
- */
- updateFlavorUsage: function() {
- if(!this.is_flavor_quota) return;
-
- var scope = this;
- var instance_count = (parseInt($("#id_count").val(), 10) || 1);
- var update_amount = 0;
-
- this.getSelectedFlavor();
-
- $(this.flavor_progress_bars).each(function(index, element) {
- var element_id = $(element).attr('id');
- var progress_stat = element_id.match(/^quota_(.+)/)[1];
-
- if(progress_stat === undefined) {
- return;
- } else if(progress_stat === 'instances') {
- update_amount = instance_count;
- } else if (scope.selected_flavor) {
- update_amount = (scope.selected_flavor[progress_stat] * instance_count);
- }
-
- scope.updateUsageFor(element, update_amount);
- });
- },
-
- // Does the math to calculate what percentage to update a progress bar by.
- updateUsageFor: function(progress_element, increment_by) {
- progress_element = $(progress_element);
-
- //var update_indicator = progress_element.find('.progress_bar_selected');
- var quota_limit = parseInt(progress_element.attr('data-quota-limit'), 10);
- var quota_used = parseInt(progress_element.attr('data-quota-used'), 10);
- var percentage_to_update = ((increment_by / quota_limit) * 100);
- var percentage_used = ((quota_used / quota_limit) * 100);
-
- this.update($(progress_element).attr('id'), percentage_to_update);
- },
-
- // Create a new d3 bar and populate it with the current amount used
- drawUsed: function(element, used) {
- var w = "100%";
- var h = 20;
- var lvl_curve = 4;
- var bkgrnd = "#F2F2F2";
- var frgrnd = "#006CCF";
- var full = "#D0342B";
- var addition = "#00D300";
- var nearlyfull = "orange";
-
- // Horizontal Bars
- var bar = d3.select("#"+element).append("svg:svg")
- .attr("class", "chart")
- .attr("width", w)
- .attr("height", h)
- .style("background-color", "white")
- .append("g")
-
- // background - unused resources
- bar.append("rect")
- .attr("y", 0)
- .attr("width", w)
- .attr("height", h)
- .attr("rx", lvl_curve)
- .attr("ry", lvl_curve)
- .style("fill", bkgrnd)
- .style("stroke", "#CCCCCC")
- .style("stroke-width", 1)
-
- // new resources
- bar.append("rect")
- .attr("y",0)
- .attr("class", "newbar")
- .attr("width", 0)
- .attr("height", h)
- .attr("rx", lvl_curve)
- .attr("ry", lvl_curve)
- .style("fill", function () { return addition; })
-
- // used resources
- var used_bar = bar.insert("rect")
- .attr("class", "usedbar")
- .attr("y", 0)
- .attr("id", "test")
- .attr("width", 0)
- .attr("height", h)
- .attr("rx", lvl_curve)
- .attr("ry", lvl_curve)
- .style("fill", function () { return frgrnd })
- .attr("d", used)
- .transition()
- .duration(500)
- .attr("width", used + "%")
- .style("fill", function () {
- if (used >= 100) { return full; }
- else if (used >= 80) { return nearlyfull; }
- else { return frgrnd; }
- })
- },
-
- // Update the progress Bar
- update: function(element, value) {
- var full = "#D0342B";
- var addition = "#00D300";
- var already_used = parseInt(d3.select("#"+element).select(".usedbar").attr("d"))
- d3.select("#"+element).select(".newbar")
- .transition()
- .duration(500)
- .attr("width", function () {
- if ((value + already_used) >= 100) { return "100%"; }
- else { return (value + already_used)+ "%"; }
- })
- .style("fill", function() {
- if (value > (100 - already_used)) { return full }
- else {return addition }
- });
-
- },
-
- /*
- Attaches event handlers for the form elements associated with the
- progress bars.
- */
- _attachInputHandlers: function() {
- var scope = this;
-
- if(this.is_flavor_quota) {
- var eventCallback = function(evt) {
- scope.showFlavorDetails();
- scope.updateFlavorUsage();
- };
-
- $('#id_flavor').on('change', eventCallback);
- $('#id_count').on('keyup', eventCallback);
- }
-
- $(this.user_value_form_inputs).each(function(index, element) {
- $(element).on('keyup', function(evt) {
- var progress_element = $('div[data-progress-indicator-for=' + $(evt.target).attr('id') + ']');
- var integers_in_input = $(evt.target).val().match(/\d+/g);
- var user_integer;
-
- if(integers_in_input === null) {
- user_integer = 0;
- } else if(integers_in_input.length > 1) {
- /*
- Join all the numbers together that have been typed in. This takes
- care of junk input like "dd8d72n3k" and uses just the digits in
- that input, resulting in "8723".
- */
- user_integer = integers_in_input.join('');
- } else if(integers_in_input.length == 1) {
- user_integer = integers_in_input[0];
- }
-
- var progress_amount = parseInt(user_integer, 10);
-
- scope.updateUsageFor(progress_element, progress_amount);
- });
- });
- },
-
- /*
- Animate the progress bars of elements which indicate they should
- automatically be incremented, as opposed to elements which trigger
- progress updates based on form element input or changes.
- */
- _initialAnimations: function() {
- var scope = this;
-
- $(this.auto_value_progress_bars).each(function(index, element) {
- var auto_progress = $(element);
- var update_amount = parseInt(auto_progress.attr('data-progress-indicator-step-by'), 10);
-
- scope.updateUsageFor(auto_progress, update_amount);
- });
- },
-
- // Draw the initial d3 bars
- _initialCreation: function(bars) {
- // Draw the initial progress bars
- var scope = this;
- $(bars).each(function(index, element) {
- var progress_element = $(element);
-
- var quota_limit = parseInt(progress_element.attr('data-quota-limit'), 10);
- var quota_used = parseInt(progress_element.attr('data-quota-used'), 10);
-
- if (!isNaN(quota_limit) && !isNaN(quota_used)) {
- var percentage_used = ((quota_used / quota_limit) * 100);
- } else { // If NaN percentage_used is 0
- var percentage_used = 0;
- }
-
- scope.drawUsed($(element).attr('id'), percentage_used);
- });
- }
-};
diff --git a/horizon/static/horizon/js/horizon.tables.js b/horizon/static/horizon/js/horizon.tables.js
deleted file mode 100644
index 468213c1..00000000
--- a/horizon/static/horizon/js/horizon.tables.js
+++ /dev/null
@@ -1,392 +0,0 @@
-/* Namespace for core functionality related to DataTables. */
-horizon.datatables = {
- update: function () {
- var $rows_to_update = $('tr.status_unknown.ajax-update');
- if ($rows_to_update.length) {
- var interval = $rows_to_update.attr('data-update-interval'),
- $table = $rows_to_update.closest('table'),
- decay_constant = $table.attr('decay_constant');
-
- // Do not update this row if the action column is expanded
- if ($rows_to_update.find('.actions_column .btn-group.open').length) {
- // Wait and try to update again in next interval instead
- setTimeout(horizon.datatables.update, interval);
- // Remove interval decay, since this will not hit server
- $table.removeAttr('decay_constant');
- return;
- }
- // Trigger the update handlers.
- $rows_to_update.each(function(index, row) {
- var $row = $(this),
- $table = $row.closest('table.datatable');
- horizon.ajax.queue({
- url: $row.attr('data-update-url'),
- error: function (jqXHR, textStatus, errorThrown) {
- switch (jqXHR.status) {
- // A 404 indicates the object is gone, and should be removed from the table
- case 404:
- // Update the footer count and reset to default empty row if needed
- var $footer, row_count, footer_text, colspan, template, params, $empty_row;
-
- // existing count minus one for the row we're removing
- horizon.datatables.update_footer_count($table, -1);
-
- if(row_count === 0) {
- colspan = $table.find('th[colspan]').attr('colspan');
- template = horizon.templates.compiled_templates["#empty_row_template"];
- params = {"colspan": colspan};
- empty_row = template.render(params);
- $row.replaceWith(empty_row);
- } else {
- $row.remove();
- }
- // Reset tablesorter's data cache.
- $table.trigger("update");
- break;
- default:
- horizon.utils.log(gettext("An error occurred while updating."));
- $row.removeClass("ajax-update");
- $row.find("i.ajax-updating").remove();
- break;
- }
- },
- success: function (data, textStatus, jqXHR) {
- var $new_row = $(data);
-
- if ($new_row.hasClass('status_unknown')) {
- var spinner_elm = $new_row.find("td.status_unknown:last");
-
- if ($new_row.find('a.btn-action-required').length > 0) {
- spinner_elm.prepend(
- $("<div />")
- .addClass("action_required_img")
- .append(
- $("<img />")
- .attr("src", "/static/dashboard/img/action_required.png")));
- } else {
- // Replacing spin.js here with an animated gif to reduce CPU
- spinner_elm.prepend(
- $("<div />")
- .addClass("loading_gif")
- .append(
- $("<img />")
- .attr("src", "/static/dashboard/img/loading.gif")));
- }
- }
-
- // Only replace row if the html content has changed
- if($new_row.html() != $row.html()) {
- if($row.find(':checkbox').is(':checked')) {
- // Preserve the checkbox if it's already clicked
- $new_row.find(':checkbox').prop('checked', true);
- }
- $row.replaceWith($new_row);
- // Reset tablesorter's data cache.
- $table.trigger("update");
- // Reset decay constant.
- $table.removeAttr('decay_constant');
- }
- },
- complete: function (jqXHR, textStatus) {
- // Revalidate the button check for the updated table
- horizon.datatables.validate_button();
- }
- });
- });
-
- // Set interval decay to this table, and increase if it already exist
- if(decay_constant === undefined) {
- decay_constant = 1;
- } else {
- decay_constant++;
- }
- $table.attr('decay_constant', decay_constant);
- // Poll until there are no rows in an "unknown" state on the page.
- next_poll = interval * decay_constant;
- // Limit the interval to 30 secs
- if(next_poll > 30 * 1000) next_poll = 30 * 1000;
- setTimeout(horizon.datatables.update, next_poll);
- }
- },
-
- validate_button: function () {
- // Disable form button if checkbox are not checked
- $("form").each(function (i) {
- var checkboxes = $(this).find(":checkbox");
- if(!checkboxes.length) {
- // Do nothing if no checkboxes in this form
- return;
- }
- if(!checkboxes.filter(":checked").length) {
- $(this).find(".table_actions button.btn-danger").addClass("disabled");
- }
- });
- }
-};
-
-/* Generates a confirmation modal dialog for the given action. */
-horizon.datatables.confirm = function (action) {
- var $action = $(action),
- $modal_parent = $(action).closest('.modal'),
- name_array = new Array(),
- closest_table_id, action_string, name_string,
- title, body, modal, form;
- if($action.hasClass("disabled")) {
- return;
- }
- action_string = $action.text();
- name_string = "";
- // Add the display name defined by table.get_object_display(datum)
- closest_table_id = $(action).closest("table").attr("id");
- // Check if data-display attribute is available
- if ($("#"+closest_table_id+" tr[data-display]").length > 0) {
- name_string = gettext("You have selected ");
- if($(action).closest("div").hasClass("table_actions")) {
- // One or more checkboxes selected
- $("#"+closest_table_id+" tr[data-display]").has(":checkbox:checked").each(function() {
- name_array.push(" \"" + $(this).attr("data-display") + "\"");
- });
- name_array.join(", ");
- name_string += name_array.toString() + ". ";
- } else {
- // If no checkbox is selected
- name_string += " \"" + $(action).closest("tr").attr("data-display") + "\". ";
- }
- }
- title = gettext("Confirm ") + action_string;
- body = name_string + gettext("Please confirm your selection. This action cannot be undone.");
- modal = horizon.modals.create(title, body, action_string);
- modal.modal();
- if($modal_parent.length) {
- var child_backdrop = modal.next('.modal-backdrop');
- // re-arrange z-index for these stacking modal
- child_backdrop.css('z-index', $modal_parent.css('z-index')+10);
- modal.css('z-index', child_backdrop.css('z-index')+10);
- }
- modal.find('.btn-primary').click(function (evt) {
- form = $action.closest('form');
- form.append("<input type='hidden' name='" + $action.attr('name') + "' value='" + $action.attr('value') + "'/>");
- form.submit();
- modal.modal('hide');
- horizon.modals.modal_spinner(gettext("Working"));
- return false;
- });
- return modal;
-};
-
-$.tablesorter.addParser({
- // set a unique id
- id: 'sizeSorter',
- is: function(s) {
- // Not an auto-detected parser
- return false;
- },
- // compare int values
- format: function(s) {
- var sizes = {BYTE: 0, B: 0, KB: 1, MB: 2,
- GB: 3, TB: 4, PB: 5};
- var regex = /([\d\.,]+)\s*(byte|B|KB|MB|GB|TB|PB)+/i;
- var match = s.match(regex);
- if (match && match.length === 3){
- return parseFloat(match[1]) *
- Math.pow(1024, sizes[match[2].toUpperCase()]);
- }
- return parseInt(s, 10);
- },
- type: 'numeric'
-});
-
-horizon.datatables.update_footer_count = function (el, modifier) {
- var $el = $(el),
- $browser, $footer, row_count, footer_text_template, footer_text;
- if (!modifier) {
- modifier = 0;
- }
- // code paths for table or browser footers...
- $browser = $el.closest("#browser_wrapper");
- if ($browser.length) {
- $footer = $browser.find('.tfoot span.content_table_count');
- }
- else {
- $footer = $el.find('tfoot span.table_count');
- }
- row_count = $el.find('tbody tr:visible').length + modifier - $el.find('.empty').length;
- footer_text_template = ngettext("Displaying %s item", "Displaying %s items", row_count);
- footer_text = interpolate(footer_text_template, [row_count]);
- $footer.text(footer_text);
-};
-
-horizon.datatables.add_no_results_row = function (table) {
- // Add a "no results" row if there are no results.
- template = horizon.templates.compiled_templates["#empty_row_template"];
- if (!table.find("tbody tr:visible").length && typeof(template) !== "undefined") {
- colspan = table.find("th[colspan]").attr('colspan');
- params = {"colspan": colspan};
- table.find("tbody").append(template.render(params));
- }
-};
-
-horizon.datatables.remove_no_results_row = function (table) {
- table.find("tr.empty").remove();
-};
-
-/*
- * Fixes the striping of the table after filtering results.
-**/
-horizon.datatables.fix_row_striping = function (table) {
- table.trigger('applyWidgetId', ['zebra']);
-};
-
-horizon.datatables.set_table_sorting = function (parent) {
-// Function to initialize the tablesorter plugin strictly on sortable columns.
-$(parent).find("table.datatable").each(function () {
- var $table = $(this),
- header_options = {};
- // Disable if not sortable or has <= 1 item
- if ($table.find('tbody tr').not('.empty').length > 1){
- $table.find("thead th[class!='table_header']").each(function (i, val) {
- $th = $(this);
- if (!$th.hasClass('sortable')) {
- header_options[i] = {sorter: false};
- } else if ($th.data('type') == 'size'){
- header_options[i] = {sorter: 'sizeSorter'};
- } else if ($th.data('type') == 'ip'){
- header_options[i] = {sorter: 'ipAddress'};
- }
- });
- $table.tablesorter({
- headers: header_options,
- selectorHeaders: "thead th[class!='table_header']",
- cancelSelection: false
- });
- }
-});
-};
-
-horizon.datatables.add_table_checkboxes = function(parent) {
- $(parent).find('table thead .multi_select_column').each(function(index, thead) {
- if (!$(thead).find(':checkbox').length &&
- $(thead).parents('table').find('tbody :checkbox').length) {
- $(thead).append('<input type="checkbox">');
- }
- });
-};
-
-horizon.datatables.set_table_query_filter = function (parent) {
- $(parent).find('table').each(function (index, elm) {
- var input = $($(elm).find('div.table_search input')),
- table_selector;
- if (input.length > 0) {
- // Disable server-side searcing if we have client-side searching since
- // (for now) the client-side is actually superior. Server-side filtering
- // remains as a noscript fallback.
- // TODO(gabriel): figure out an overall strategy for making server-side
- // filtering the preferred functional method.
- input.on('keypress', function (evt) {
- if (evt.keyCode === 13) {
- return false;
- }
- });
- input.next('button.btn-search').on('click keypress', function (evt) {
- return false;
- });
-
- // Enable the client-side searching.
- table_selector = 'table#' + $(elm).attr('id');
- input.quicksearch(table_selector + ' tbody tr', {
- 'delay': 300,
- 'loader': 'span.loading',
- 'bind': 'keyup click',
- 'show': this.show,
- 'hide': this.hide,
- onBefore: function () {
- var table = $(table_selector);
- horizon.datatables.remove_no_results_row(table);
- },
- onAfter: function () {
- var template, table, colspan, params;
- table = $(table_selector);
- horizon.datatables.update_footer_count(table);
- horizon.datatables.add_no_results_row(table);
- horizon.datatables.fix_row_striping(table);
- },
- prepareQuery: function (val) {
- return new RegExp(val, "i");
- },
- testQuery: function (query, txt, _row) {
- return query.test($(_row).find('td:not(.hidden):not(.actions_column)').text());
- }
- });
- }
- });
-};
-
-horizon.datatables.set_table_fixed_filter = function (parent) {
- $(parent).find('table.datatable').each(function (index, elm) {
- $(elm).on('click', 'div.table_filter button', function(evt) {
- var table = $(elm);
- var category = $(this).val();
- evt.preventDefault();
- horizon.datatables.remove_no_results_row(table);
- table.find('tbody tr').hide();
- table.find('tbody tr.category-' + category).show();
- horizon.datatables.update_footer_count(table);
- horizon.datatables.add_no_results_row(table);
- horizon.datatables.fix_row_striping(table);
- });
- $(elm).find('div.table_filter button').each(function (i, button) {
- // Select the first non-empty category
- if ($(button).text().indexOf(' (0)') == -1) {
- $(button).addClass('active');
- $(button).trigger('click');
- return false;
- }
- });
- });
-};
-
-horizon.addInitFunction(function() {
- horizon.datatables.validate_button();
- $('table.datatable').each(function (idx, el) {
- horizon.datatables.update_footer_count($(el), 0);
- });
- // Bind the "select all" checkbox action.
- $('div.table_wrapper, #modal_wrapper').on('click', 'table thead .multi_select_column :checkbox', function(evt) {
- var $this = $(this),
- $table = $this.closest('table'),
- is_checked = $this.prop('checked'),
- checkboxes = $table.find('tbody :visible:checkbox');
- checkboxes.prop('checked', is_checked);
- });
- // Change "select all" checkbox behaviour while any checkbox is checked/unchecked.
- $("div.table_wrapper, #modal_wrapper").on("click", 'table tbody :checkbox', function (evt) {
- var $table = $(this).closest('table');
- var $multi_select_checkbox = $table.find('thead .multi_select_column :checkbox');
- var any_unchecked = $table.find("tbody :checkbox").not(":checked");
- $multi_select_checkbox.prop('checked', !(any_unchecked.length > 0));
- });
- // Enable dangerous buttons only if one or more checkbox is checked.
- $("div.table_wrapper, #modal_wrapper").on("click", ':checkbox', function (evt) {
- var $form = $(this).closest("form");
- var any_checked = $form.find("tbody :checkbox").is(":checked");
- if(any_checked) {
- $form.find(".table_actions button.btn-danger").removeClass("disabled");
- }else {
- $form.find(".table_actions button.btn-danger").addClass("disabled");
- }
- });
-
- // Trigger run-once setup scripts for tables.
- horizon.datatables.add_table_checkboxes($('body'));
- horizon.datatables.set_table_sorting($('body'));
- horizon.datatables.set_table_query_filter($('body'));
- horizon.datatables.set_table_fixed_filter($('body'));
-
- // Also apply on tables in modal views.
- horizon.modals.addModalInitFunction(horizon.datatables.add_table_checkboxes);
- horizon.modals.addModalInitFunction(horizon.datatables.set_table_sorting);
- horizon.modals.addModalInitFunction(horizon.datatables.set_table_query_filter);
- horizon.modals.addModalInitFunction(horizon.datatables.set_table_fixed_filter);
-
- horizon.datatables.update();
-});
diff --git a/horizon/static/horizon/js/horizon.tabs.js b/horizon/static/horizon/js/horizon.tabs.js
deleted file mode 100644
index dd536c2b..00000000
--- a/horizon/static/horizon/js/horizon.tabs.js
+++ /dev/null
@@ -1,84 +0,0 @@
-horizon.tabs = {};
-
-horizon.tabs.load_tab = function (evt) {
- var $this = $(this),
- tab_id = $this.attr('data-target'),
- tab_pane = $(tab_id);
-
- // FIXME(gabriel): This style mucking shouldn't be in the javascript.
- tab_pane.append("<span style='margin-left: 30px;'>" + gettext("Loading") + "&hellip;</span>");
- tab_pane.spin(horizon.conf.spinner_options.inline);
- $(tab_pane.data().spinner.el).css('top', '9px');
- $(tab_pane.data().spinner.el).css('left', '15px');
-
- // If query params exist, append tab id.
- if(window.location.search.length > 0) {
- tab_pane.load(window.location.search + "&tab=" + tab_id.replace('#', ''));
- } else {
- tab_pane.load("?tab=" + tab_id.replace('#', ''));
- }
- $this.attr("data-loaded", "true");
- evt.preventDefault();
-};
-
-horizon.addInitFunction(function () {
- var data = horizon.cookies.read('tabs');
-
- $(".tab-content").find(".js-tab-pane").addClass("tab-pane");
- horizon.modals.addModalInitFunction(function (el) {
- $(el).find(".js-tab-pane").addClass("tab-pane");
- });
-
- $(document).on("show", ".ajax-tabs a[data-loaded='false']", horizon.tabs.load_tab);
-
- $(document).on("shown", ".nav-tabs a[data-toggle='tab']", function (evt) {
- var $tab = $(evt.target),
- $content = $($(evt.target).attr('data-target'));
- $content.find("table.datatable").each(function () {
- horizon.datatables.update_footer_count($(this));
- });
- horizon.cookies.update("tabs", $tab.closest(".nav-tabs").attr("id"), $tab.attr('data-target'));
- });
-
- // Initialize stored tab state for tab groups on this page.
- $(".nav-tabs[data-sticky-tabs='sticky']").each(function (index, item) {
- var $this = $(this),
- id = $this.attr("id"),
- active_tab = data[id];
- // Set the tab from memory if we have a "sticky" tab and the tab wasn't explicitly requested via GET.
- if (active_tab && window.location.search.indexOf("tab=") < 0) {
- $this.find("a[data-target='" + active_tab + "']").tab('show');
- }
- });
-
- // Enable keyboard navigation between tabs in a form.
- $(document).on("keydown", ".tab-pane :input:visible:last", function (evt) {
- var $this = $(this),
- next_pane = $this.closest(".tab-pane").next(".tab-pane");
- // Capture the forward-tab keypress if we have a next tab to go to.
- if (evt.which === 9 && !event.shiftKey && next_pane.length) {
- evt.preventDefault();
- $(".nav-tabs a[data-target='#" + next_pane.attr("id") + "']").tab('show');
- }
- });
- $(document).on("keydown", ".tab-pane :input:visible:first", function (evt) {
- var $this = $(this),
- prev_pane = $this.closest(".tab-pane").prev(".tab-pane");
- // Capture the forward-tab keypress if we have a next tab to go to.
- if (event.shiftKey && evt.which === 9 && prev_pane.length) {
- evt.preventDefault();
- $(".nav-tabs a[data-target='#" + prev_pane.attr("id") + "']").tab('show');
- prev_pane.find(":input:last").focus();
- console.log(prev_pane);
- }
- });
-
- $(document).on("focus", ".tab-content :input", function () {
- var $this = $(this),
- tab_pane = $this.closest(".tab-pane"),
- tab_id = tab_pane.attr('id');
- if (!tab_pane.hasClass("active")) {
- $(".nav-tabs a[data-target='#" + tab_id + "']").tab('show');
- }
- });
-});
diff --git a/horizon/static/horizon/js/horizon.templates.js b/horizon/static/horizon/js/horizon.templates.js
deleted file mode 100644
index 4c393461..00000000
--- a/horizon/static/horizon/js/horizon.templates.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Namespace for core functionality related to client-side templating. */
-horizon.templates = {
- template_ids: ["#modal_template", "#modal_chart_template", "#empty_row_template", "#alert_message_template", "#spinner-modal", "#project_user_template"],
- compiled_templates: {}
-};
-
-/* Pre-loads and compiles the client-side templates. */
-horizon.templates.compile_templates = function () {
- $.each(horizon.templates.template_ids, function (ind, template_id) {
- horizon.templates.compiled_templates[template_id] = Hogan.compile($(template_id).html());
- });
-};
-
-horizon.addInitFunction(function () {
- // Load client-side template fragments and compile them.
- horizon.templates.compile_templates();
-});
diff --git a/horizon/static/horizon/js/horizon.users.js b/horizon/static/horizon/js/horizon.users.js
deleted file mode 100644
index 41b23b31..00000000
--- a/horizon/static/horizon/js/horizon.users.js
+++ /dev/null
@@ -1,31 +0,0 @@
-horizon.user = {
-
- init: function() {
- $("#id_password").change(function () {
- if ($("#id_confirm_password").val() != "") {
- horizon.user.check_passwords_match();
- }
- });
-
- $("#id_confirm_password").change(function () {
- horizon.user.check_passwords_match();
- });
- },
-
- check_passwords_match: function() {
- var row = $("label[for='id_confirm_password']");
- var error_id = "id_confirm_password_error";
- var msg = "<span id='" + error_id + "' class='help-inline'>" + gettext("Passwords do not match.") + "</span>";
-
- var password = $("#id_password").val();
- var confirm_password = $("#id_confirm_password").val();
-
- if (password != confirm_password && $("#" + error_id).length == 0) {
- $(row).parent().addClass("error");
- $(row).after(msg);
- } else if (password == confirm_password) {
- $(row).parent().removeClass("error");
- $("#" + error_id).remove();
- }
- }
-};
diff --git a/horizon/static/horizon/js/horizon.utils.js b/horizon/static/horizon/js/horizon.utils.js
deleted file mode 100644
index 61f4859d..00000000
--- a/horizon/static/horizon/js/horizon.utils.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Utilities for common needs which aren't JS builtins. */
-horizon.utils = {
- // Log function which checks for DEBUG and the existence of a console.
- log: function () {
- if (horizon.conf.debug && typeof(console) !== "undefined" && typeof(console.log) !== "undefined") {
- console.log(arguments);
- }
- },
-
- capitalize: function(string) {
- return string.charAt(0).toUpperCase() + string.slice(1);
- },
-
- /*
- Adds commas to any integer or numbers within a string for human display.
-
- EG:
- horizon.utils.humanizeNumbers(1234); -> "1,234"
- horizon.utils.humanizeNumbers("My Total: 1234"); -> "My Total: 1,234"
- */
- humanizeNumbers: function(number) {
- return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
- },
-
- /*
- Truncate a string at the desired length. Optionally append an ellipsis
- to the end of the string.
-
- EG:
- horizon.utils.truncate("String that is too long.", 18, true); ->
- "String that is too&hellip;"
- */
- truncate: function(string, size, includeEllipsis) {
- if(string.length > size) {
- if(includeEllipsis) {
- return string.substring(0, (size - 3)) + "&hellip;";
- } else {
- return string.substring(0, size);
- }
- } else {
- return string;
- }
- }
-};
diff --git a/horizon/static/horizon/lib/d3.v3.min.js b/horizon/static/horizon/lib/d3.v3.min.js
deleted file mode 100644
index d4e9c355..00000000
--- a/horizon/static/horizon/lib/d3.v3.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-d3=function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function i(){}function u(){}function a(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function o(){}function c(n){function t(){for(var t,r=e,i=-1,u=r.length;++i<u;)(t=r[i].on)&&t.apply(this,arguments);return n}var e=[],r=new i;return t.on=function(t,i){var u,a=r.get(t);return arguments.length<2?a&&a.on:(a&&(a.on=null,e=e.slice(0,u=e.indexOf(a)).concat(e.slice(u+1)),r.remove(t)),i&&e.push(r.set(t,{on:i})),n)},t}function l(){oa.event.stopPropagation(),oa.event.preventDefault()}function f(){for(var n,t=oa.event;n=t.sourceEvent;)t=n;return t}function s(n,t){function e(){n.on(t,null)}n.on(t,function(){l(),e()},!0),setTimeout(e,0)}function h(n){for(var t=new o,e=0,r=arguments.length;++e<r;)t[arguments[e]]=c(t);return t.of=function(e,r){return function(i){try{var u=i.sourceEvent=oa.event;i.target=n,oa.event=i,t[i.type].apply(e,r)}finally{oa.event=u}}},t}function g(n,t){var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>ma&&(la.scrollX||la.scrollY)){e=oa.select(ca.body).append("svg").style("position","absolute").style("top",0).style("left",0);var i=e[0][0].getScreenCTM();ma=!(i.f||i.e),e.remove()}return ma?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var u=n.getBoundingClientRect();return[t.clientX-u.left-n.clientLeft,t.clientY-u.top-n.clientTop]}function p(n){for(var t=-1,e=n.length,r=[];++t<e;)r.push(n[t]);return r}function d(n){return Array.prototype.slice.call(n)}function m(n){return Ma(n,Ea),n}function v(n){return function(){return xa(n,this)}}function y(n){return function(){return ba(n,this)}}function M(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function i(){this.setAttribute(n,t)}function u(){this.setAttributeNS(n.space,n.local,t)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=oa.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?o:a:n.local?u:i}function x(n){return n.trim().replace(/\s+/g," ")}function _(n){return RegExp("(?:^|\\s+)"+oa.requote(n)+"(?:\\s+|$)","g")}function w(n,t){function e(){for(var e=-1;++e<i;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<i;)n[e](this,r)}n=n.trim().split(/\s+/).map(S);var i=n.length;return"function"==typeof t?r:e}function S(n){var t=_(n);return function(e,r){if(i=e.classList)return r?i.add(n):i.remove(n);var i=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(i)||e.setAttribute("class",x(i+" "+n))):e.setAttribute("class",x(i.replace(t," ")))}}function E(n,t,e){function r(){this.style.removeProperty(n)}function i(){this.style.setProperty(n,t,e)}function u(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?u:i}function k(n,t){function e(){delete this[n]}function r(){this[n]=t}function i(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?i:r}function A(n){return{__data__:n}}function N(n){return function(){return Sa(this,n)}}function q(n){return arguments.length||(n=oa.ascending),function(t,e){return!t-!e||n(t.__data__,e.__data__)}}function T(){}function C(n,t,e){function r(){var t=this[a];t&&(this.removeEventListener(n,t,t.$),delete this[a])}function i(){var i=c(t,va(arguments));r.call(this),this.addEventListener(n,this[a]=i,i.$=e),i._=t}function u(){var t,e=RegExp("^__on([^.]+)"+oa.requote(n)+"$");for(var r in this)if(t=r.match(e)){var i=this[r];this.removeEventListener(t[1],i,i.$),delete this[r]}}var a="__on"+n,o=n.indexOf("."),c=z;o>0&&(n=n.substring(0,o));var l=Na.get(n);return l&&(n=l,c=D),o?t?i:r:t?T:u}function z(n,t){return function(e){var r=oa.event;oa.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{oa.event=r}}}function D(n,t){var e=z(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||r.compareDocumentPosition(t)&8)||e.call(t,n)}}function j(n,t){for(var e=0,r=n.length;r>e;e++)for(var i,u=n[e],a=0,o=u.length;o>a;a++)(i=u[a])&&t(i,a,e);return n}function L(n){return Ma(n,qa),n}function F(){}function H(n,t,e){return new P(n,t,e)}function P(n,t,e){this.h=n,this.s=t,this.l=e}function R(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(a-u)*n/60:180>n?a:240>n?u+(a-u)*(240-n)/60:u}function i(n){return Math.round(r(n)*255)}var u,a;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,a=.5>=e?e*(1+t):e+t-e*t,u=2*e-a,et(i(n+120),i(n),i(n-120))}function O(n){return n>0?1:0>n?-1:0}function Y(n){return Math.acos(Math.max(-1,Math.min(1,n)))}function U(n){return n>1?La/2:-1>n?-La/2:Math.asin(n)}function I(n){return(Math.exp(n)-Math.exp(-n))/2}function V(n){return(Math.exp(n)+Math.exp(-n))/2}function X(n){return(n=Math.sin(n/2))*n}function Z(n,t,e){return new B(n,t,e)}function B(n,t,e){this.h=n,this.c=t,this.l=e}function $(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),J(e,Math.cos(n*=Ha)*t,Math.sin(n)*t)}function J(n,t,e){return new G(n,t,e)}function G(n,t,e){this.l=n,this.a=t,this.b=e}function K(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=Q(i)*Ya,r=Q(r)*Ua,u=Q(u)*Ia,et(tt(3.2404542*i-1.5371385*r-.4985314*u),tt(-.969266*i+1.8760108*r+.041556*u),tt(.0556434*i-.2040259*r+1.0572252*u))}function W(n,t,e){return n>0?Z(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):Z(0/0,0/0,n)}function Q(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function nt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function tt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function et(n,t,e){return new rt(n,t,e)}function rt(n,t,e){this.r=n,this.g=t,this.b=e}function it(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function ut(n,t,e){var r,i,u,a=0,o=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(lt(i[0]),lt(i[1]),lt(i[2]))}return(u=Za.get(n))?t(u.r,u.g,u.b):(null!=n&&n.charAt(0)==="#"&&(n.length===4?(a=n.charAt(1),a+=a,o=n.charAt(2),o+=o,c=n.charAt(3),c+=c):n.length===7&&(a=n.substring(1,3),o=n.substring(3,5),c=n.substring(5,7)),a=parseInt(a,16),o=parseInt(o,16),c=parseInt(c,16)),t(a,o,c))}function at(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),a=Math.max(n,t,e),o=a-u,c=(a+u)/2;return o?(i=.5>c?o/(a+u):o/(2-a-u),r=n==a?(t-e)/o+(e>t?6:0):t==a?(e-n)/o+2:(n-t)/o+4,r*=60):(r=0/0,i=c>0&&1>c?0:r),H(r,i,c)}function ot(n,t,e){n=ct(n),t=ct(t),e=ct(e);var r=nt((.4124564*n+.3575761*t+.1804375*e)/Ya),i=nt((.2126729*n+.7151522*t+.072175*e)/Ua),u=nt((.0193339*n+.119192*t+.9503041*e)/Ia);return J(116*i-16,500*(r-i),200*(i-u))}function ct(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function lt(n){var t=parseFloat(n);return n.charAt(n.length-1)==="%"?Math.round(2.55*t):t}function ft(n){return"function"==typeof n?n:function(){return n}}function st(n){return n}function ht(n){return n.length===1?function(t,e){n(null==t?e:null)}:n}function gt(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var a=oa.xhr(n,t,u);return a.row=function(n){return arguments.length?a.response((e=n)==null?r:i(n)):e},a.row(e)}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function a(t){return t.map(o).join(n)}function o(n){return c.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var c=RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return a;if(i)return i=!1,u;var t=f;if(n.charCodeAt(t)===34){for(var e=t;e++<c;)if(n.charCodeAt(e)===34){if(n.charCodeAt(e+1)!==34)break;++e}f=e+2;var r=n.charCodeAt(e+1);return 13===r?(i=!0,n.charCodeAt(e+2)===10&&++f):10===r&&(i=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;c>f;){var r=n.charCodeAt(f++),o=1;if(10===r)i=!0;else if(13===r)i=!0,n.charCodeAt(f)===10&&(++f,++o);else if(r!==l)continue;return n.substring(t,f-o)}return n.substring(t)}for(var r,i,u={},a={},o=[],c=n.length,f=0,s=0;(r=e())!==a;){for(var h=[];r!==u&&r!==a;)h.push(r),r=e();(!t||(h=t(h,s++)))&&o.push(h)}return o},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new u,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(a).join("\n")},e}function pt(){for(var n,t=Date.now(),e=Ka;e;)n=t-e.then,n>=e.delay&&(e.flush=e.callback(n)),e=e.next;var r=dt()-t;r>24?(isFinite(r)&&(clearTimeout($a),$a=setTimeout(pt,r)),Ba=0):(Ba=1,Wa(pt))}function dt(){for(var n=null,t=Ka,e=1/0;t;)t.flush?(delete Ga[t.callback.id],t=n?n.next=t.next:Ka=t.next):(e=Math.min(e,t.then+t.delay),t=(n=t).next);return e}function mt(n,t){var e=Math.pow(10,Math.abs(8-t)*3);return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function vt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function yt(n){return n+""}function Mt(n,t){n&&co.hasOwnProperty(n.type)&&co[n.type](n,t)}function xt(n,t,e){var r,i=-1,u=n.length-e;for(t.lineStart();++i<u;)r=n[i],t.point(r[0],r[1]);t.lineEnd()}function bt(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)xt(n[e],t,1);t.polygonEnd()}function _t(){function n(n,t){n*=Ha,t=t*Ha/2+La/4;var e=n-r,a=Math.cos(t),o=Math.sin(t),c=u*o,l=fo,f=so,s=i*a+c*Math.cos(e),h=c*Math.sin(e);fo=l*s-f*h,so=f*s+l*h,r=n,i=a,u=o}var t,e,r,i,u;ho.point=function(a,o){ho.point=n,r=(t=a)*Ha,i=Math.cos(o=(e=o)*Ha/2+La/4),u=Math.sin(o)},ho.lineEnd=function(){n(t,e)}}function wt(n){function t(n,t){r>n&&(r=n),n>u&&(u=n),i>t&&(i=t),t>a&&(a=t)}function e(){o.point=o.lineEnd=T}var r,i,u,a,o={point:t,lineStart:T,lineEnd:T,polygonStart:function(){o.lineEnd=e},polygonEnd:function(){o.point=t}};return function(t){return a=u=-(r=i=1/0),oa.geo.stream(t,n(o)),[[r,i],[u,a]]}}function St(n,t){if(!go){++po,n*=Ha;var e=Math.cos(t*=Ha);mo+=(e*Math.cos(n)-mo)/po,vo+=(e*Math.sin(n)-vo)/po,yo+=(Math.sin(t)-yo)/po}}function Et(){var n,t;go=1,kt(),go=2;var e=Mo.point;Mo.point=function(r,i){e(n=r,t=i)},Mo.lineEnd=function(){Mo.point(n,t),At(),Mo.lineEnd=At}}function kt(){function n(n,i){n*=Ha;var u=Math.cos(i*=Ha),a=u*Math.cos(n),o=u*Math.sin(n),c=Math.sin(i),l=Math.atan2(Math.sqrt((l=e*c-r*o)*l+(l=r*a-t*c)*l+(l=t*o-e*a)*l),t*a+e*o+r*c);po+=l,mo+=l*(t+(t=a)),vo+=l*(e+(e=o)),yo+=l*(r+(r=c))}var t,e,r;go>1||(1>go&&(go=1,po=mo=vo=yo=0),Mo.point=function(i,u){i*=Ha;var a=Math.cos(u*=Ha);t=a*Math.cos(i),e=a*Math.sin(i),r=Math.sin(u),Mo.point=n})}function At(){Mo.point=St}function Nt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function qt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function Tt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Ct(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function zt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Dt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function jt(){return!0}function Lt(n){return[Math.atan2(n[1],n[0]),Math.asin(Math.max(-1,Math.min(1,n[2])))]}function Ft(n,t){return Math.abs(n[0]-t[0])<Fa&&Math.abs(n[1]-t[1])<Fa}function Ht(n,t,e,r,i){var u=[],a=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(Ft(e,r)){i.lineStart();for(var o=0;t>o;++o)i.point((e=n[o])[0],e[1]);return i.lineEnd(),void 0}var c={point:e,points:n,other:null,visited:!1,entry:!0,subject:!0},l={point:e,points:[e],other:c,visited:!1,entry:!1,subject:!1};c.other=l,u.push(c),a.push(l),c={point:r,points:[r],other:null,visited:!1,entry:!1,subject:!0},l={point:r,points:[r],other:c,visited:!1,entry:!0,subject:!1},c.other=l,u.push(c),a.push(l)}}),a.sort(t),Pt(u),Pt(a),u.length){if(e)for(var o=1,c=!e(a[0].point),l=a.length;l>o;++o)a[o].entry=c=!c;for(var f,s,h,g=u[0];;){for(f=g;f.visited;)if((f=f.next)===g)return;s=f.points,i.lineStart();do{if(f.visited=f.other.visited=!0,f.entry){if(f.subject)for(var o=0;o<s.length;o++)i.point((h=s[o])[0],h[1]);else r(f.point,f.next.point,1,i);f=f.next}else{if(f.subject){s=f.prev.points;for(var o=s.length;--o>=0;)i.point((h=s[o])[0],h[1])}else r(f.point,f.prev.point,-1,i);f=f.prev}f=f.other,s=f.points}while(!f.visited);i.lineEnd()}}}function Pt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r<t;)i.next=e=n[r],e.prev=i,i=e;i.next=e=n[0],e.prev=i}}function Rt(n,t,e){return function(r){function i(t,e){n(t,e)&&r.point(t,e)}function u(n,t){m.point(n,t)}function a(){v.point=u,m.lineStart()}function o(){v.point=i,m.lineEnd()}function c(n,t){M.point(n,t),d.push([n,t])}function l(){M.lineStart(),d=[]}function f(){c(d[0][0],d[0][1]),M.lineEnd();var n,t=M.clean(),e=y.buffer(),i=e.length;if(!i)return p=!0,g+=Ut(d,-1),d=null,void 0;if(d=null,1&t){n=e[0],h+=Ut(n,1);var u,i=n.length-1,a=-1;for(r.lineStart();++a<i;)r.point((u=n[a])[0],u[1]);return r.lineEnd(),void 0}i>1&&2&t&&e.push(e.pop().concat(e.shift())),s.push(e.filter(Ot))}var s,h,g,p,d,m=t(r),v={point:i,lineStart:a,lineEnd:o,polygonStart:function(){v.point=c,v.lineStart=l,v.lineEnd=f,p=!1,g=h=0,s=[],r.polygonStart()},polygonEnd:function(){v.point=i,v.lineStart=a,v.lineEnd=o,s=oa.merge(s),s.length?Ht(s,It,null,e,r):(-Fa>h||p&&-Fa>g)&&(r.lineStart(),e(null,null,1,r),r.lineEnd()),r.polygonEnd(),s=null},sphere:function(){r.polygonStart(),r.lineStart(),e(null,null,1,r),r.lineEnd(),r.polygonEnd()}},y=Yt(),M=t(y);return v}}function Ot(n){return n.length>1}function Yt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:T,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){if(!(e=n.length))return 0;for(var e,r,i,u=0,a=0,o=n[0],c=o[0],l=o[1],f=Math.cos(l),s=Math.atan2(t*Math.sin(c)*f,Math.sin(l)),h=1-t*Math.cos(c)*f,g=s;++u<e;)o=n[u],f=Math.cos(l=o[1]),r=Math.atan2(t*Math.sin(c=o[0])*f,Math.sin(l)),i=1-t*Math.cos(c)*f,Math.abs(h-2)<Fa&&Math.abs(i-2)<Fa||(Math.abs(i)<Fa||Math.abs(h)<Fa||(Math.abs(Math.abs(r-s)-La)<Fa?i+h>2&&(a+=4*(r-s)):a+=Math.abs(h-2)<Fa?4*(r-g):((3*La+r-s)%(2*La)-La)*(h+i)),g=s,s=r,h=i);return a}function It(n,t){return((n=n.point)[0]<0?n[1]-La/2-Fa:La/2-n[1])-((t=t.point)[0]<0?t[1]-La/2-Fa:La/2-t[1])}function Vt(n){var t,e=0/0,r=0/0,i=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(u,a){var o=u>0?La:-La,c=Math.abs(u-e);Math.abs(c-La)<Fa?(n.point(e,r=(r+a)/2>0?La/2:-La/2),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(o,r),n.point(u,r),t=0):i!==o&&c>=La&&(Math.abs(e-i)<Fa&&(e-=i*Fa),Math.abs(u-o)<Fa&&(u-=o*Fa),r=Xt(e,r,u,a),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(o,r),t=0),n.point(e=u,r=a),i=o},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Xt(n,t,e,r){var i,u,a=Math.sin(n-e);return Math.abs(a)>Fa?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*a)):(t+r)/2}function Zt(n,t,e,r){var i;if(null==n)i=e*La/2,r.point(-La,i),r.point(0,i),r.point(La,i),r.point(La,0),r.point(La,-i),r.point(0,-i),r.point(-La,-i),r.point(-La,0),r.point(-La,i);else if(Math.abs(n[0]-t[0])>Fa){var u=(n[0]<t[0]?1:-1)*La;i=e*u/2,r.point(-u,i),r.point(0,i),r.point(u,i)}else r.point(t[0],t[1])}function Bt(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,c,l,f;return{lineStart:function(){l=c=!1,f=1},point:function(s,h){var g,p=[s,h],d=t(s,h),m=a?d?0:i(s,h):d?i(s+(0>s?La:-La),h):0;if(!e&&(l=c=d)&&n.lineStart(),d!==c&&(g=r(e,p),(Ft(e,g)||Ft(p,g))&&(p[0]+=Fa,p[1]+=Fa,d=t(p[0],p[1]))),d!==c)f=0,d?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(o&&e&&a^d){var v;m&u||!(v=r(p,e,!0))||(f=0,a?(n.lineStart(),n.point(v[0][0],v[0][1]),n.point(v[1][0],v[1][1]),n.lineEnd()):(n.point(v[1][0],v[1][1]),n.lineEnd(),n.lineStart(),n.point(v[0][0],v[0][1])))}!d||e&&Ft(e,p)||n.point(p[0],p[1]),e=p,c=d,u=m},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return f|(l&&c)<<1}}}function r(n,t,e){var r=Nt(n),i=Nt(t),a=[1,0,0],o=Tt(r,i),c=qt(o,o),l=o[0],f=c-l*l;if(!f)return!e&&n;var s=u*c/f,h=-u*l/f,g=Tt(a,o),p=zt(a,s),d=zt(o,h);Ct(p,d);var m=g,v=qt(p,m),y=qt(m,m),M=v*v-y*(qt(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=zt(m,(-v-x)/y);if(Ct(b,p),b=Lt(b),!e)return b;var _,w=n[0],S=t[0],E=n[1],k=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=Math.abs(A-La)<Fa,q=N||Fa>A;if(!N&&E>k&&(_=E,E=k,k=_),q?N?E+k>0^b[1]<(Math.abs(b[0]-w)<Fa?E:k):E<=b[1]&&b[1]<=k:A>La^(w<=b[0]&&b[0]<=S)){var T=zt(m,(-v+x)/y);return Ct(T,p),[b,Lt(T)]}}}function i(t,e){var r=a?n:La-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),a=u>0,o=Math.abs(u)>Fa,c=ae(n,6*Ha);return Rt(t,e,c)}function $t(n,t,e,r){function i(r,i){return Math.abs(r[0]-n)<Fa?i>0?0:3:Math.abs(r[0]-e)<Fa?i>0?2:1:Math.abs(r[1]-t)<Fa?i>0?1:0:i>0?3:2}function u(n,t){return a(n.point,t.point)}function a(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}function o(i,u){var a=u[0]-i[0],o=u[1]-i[1],c=[0,1];return Math.abs(a)<Fa&&Math.abs(o)<Fa?n<=i[0]&&i[0]<=e&&t<=i[1]&&i[1]<=r:Jt(n-i[0],a,c)&&Jt(i[0]-e,-a,c)&&Jt(t-i[1],o,c)&&Jt(i[1]-r,-o,c)?(c[1]<1&&(u[0]=i[0]+c[1]*a,u[1]=i[1]+c[1]*o),c[0]>0&&(i[0]+=c[0]*a,i[1]+=c[0]*o),!0):!1}return function(c){function l(u){var a=i(u,-1),o=f([0===a||3===a?n:e,a>1?r:t]);return o}function f(n){for(var t=0,e=M.length,r=n[1],i=0;e>i;++i)for(var u=1,a=M[i],o=a.length,c=a[0];o>u;++u)b=a[u],c[1]<=r?b[1]>r&&s(c,b,n)>0&&++t:b[1]<=r&&s(c,b,n)<0&&--t,c=b;return 0!==t}function s(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(e[0]-n[0])*(t[1]-n[1])}function h(u,o,c,l){var f=0,s=0;if(null==u||(f=i(u,c))!==(s=i(o,c))||a(u,o)<0^c>0){do l.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+c+4)%4)!==s)}else l.point(o[0],o[1])}function g(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function p(n,t){g(n,t)&&c.point(n,t)}function d(){C.point=v,M&&M.push(x=[]),N=!0,A=!1,E=k=0/0}function m(){y&&(v(_,w),S&&A&&T.rejoin(),y.push(T.buffer())),C.point=p,A&&c.lineEnd()}function v(n,t){n=Math.max(-bo,Math.min(bo,n)),t=Math.max(-bo,Math.min(bo,t));var e=g(n,t);if(M&&x.push([n,t]),N)_=n,w=t,S=e,N=!1,e&&(c.lineStart(),c.point(n,t));else if(e&&A)c.point(n,t);else{var r=[E,k],i=[n,t];o(r,i)?(A||(c.lineStart(),c.point(r[0],r[1])),c.point(i[0],i[1]),e||c.lineEnd()):(c.lineStart(),c.point(n,t))}E=n,k=t,A=e}var y,M,x,_,w,S,E,k,A,N,q=c,T=Yt(),C={point:p,lineStart:d,lineEnd:m,polygonStart:function(){c=T,y=[],M=[]},polygonEnd:function(){c=q,(y=oa.merge(y)).length?(c.polygonStart(),Ht(y,u,l,h,c),c.polygonEnd()):f([n,t])&&(c.polygonStart(),c.lineStart(),h(null,null,1,c),c.lineEnd(),c.polygonEnd()),y=M=x=null}};return C}}function Jt(n,t,e){if(Math.abs(t)<Fa)return 0>=n;var r=n/t;if(t>0){if(r>e[1])return!1;r>e[0]&&(e[0]=r)}else{if(r<e[0])return!1;r<e[1]&&(e[1]=r)}return!0}function Gt(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Kt(n){function t(t){function r(e,r){e=n(e,r),t.point(e[0],e[1])}function u(){f=0/0,d.point=a,t.lineStart()}function a(r,u){var a=Nt([r,u]),o=n(r,u);e(f,s,l,h,g,p,f=o[0],s=o[1],l=r,h=a[0],g=a[1],p=a[2],i,t),t.point(f,s)}function o(){d.point=r,t.lineEnd()}function c(){var n,r,c,m,v,y,M;u(),d.point=function(t,e){a(n=t,r=e),c=f,m=s,v=h,y=g,M=p,d.point=a},d.lineEnd=function(){e(f,s,l,h,g,p,c,m,n,v,y,M,i,t),d.lineEnd=o,o()}}var l,f,s,h,g,p,d={point:r,lineStart:u,lineEnd:o,polygonStart:function(){t.polygonStart(),d.lineStart=c},polygonEnd:function(){t.polygonEnd(),d.lineStart=u}};return d}function e(t,i,u,a,o,c,l,f,s,h,g,p,d,m){var v=l-t,y=f-i,M=v*v+y*y;if(M>4*r&&d--){var x=a+h,b=o+g,_=c+p,w=Math.sqrt(x*x+b*b+_*_),S=Math.asin(_/=w),E=Math.abs(Math.abs(_)-1)<Fa?(u+s)/2:Math.atan2(b,x),k=n(E,S),A=k[0],N=k[1],q=A-t,T=N-i,C=y*q-v*T;(C*C/M>r||Math.abs((v*q+y*T)/M-.5)>.3)&&(e(t,i,u,a,o,c,A,N,E,x/=w,b/=w,_,d,m),m.point(A,N),e(A,N,E,x,b,_,l,f,s,h,g,p,d,m))}}var r=.5,i=16;return t.precision=function(n){return arguments.length?(i=(r=n*n)>0&&16,t):Math.sqrt(r)},t}function Wt(n){return Qt(function(){return n})()}function Qt(n){function t(n){return n=a(n[0]*Ha,n[1]*Ha),[n[0]*f+o,c-n[1]*f]}function e(n){return n=a.invert((n[0]-o)/f,(c-n[1])/f),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Gt(u=ee(d,m,v),i);var n=i(g,p);return o=s-n[0]*f,c=h+n[1]*f,t}var i,u,a,o,c,l=Kt(function(n,t){return n=i(n,t),[n[0]*f+o,c-n[1]*f]}),f=150,s=480,h=250,g=0,p=0,d=0,m=0,v=0,y=xo,M=st,x=null,b=null;return t.stream=function(n){return ne(u,y(l(M(n))))},t.clipAngle=function(n){return arguments.length?(y=null==n?(x=n,xo):Bt((x=+n)*Ha),t):x},t.clipExtent=function(n){return arguments.length?(b=n,M=null==n?st:$t(n[0][0],n[0][1],n[1][0],n[1][1]),t):b},t.scale=function(n){return arguments.length?(f=+n,r()):f},t.translate=function(n){return arguments.length?(s=+n[0],h=+n[1],r()):[s,h]},t.center=function(n){return arguments.length?(g=n[0]%360*Ha,p=n[1]%360*Ha,r()):[g*Pa,p*Pa]},t.rotate=function(n){return arguments.length?(d=n[0]%360*Ha,m=n[1]%360*Ha,v=n.length>2?n[2]%360*Ha:0,r()):[d*Pa,m*Pa,v*Pa]},oa.rebind(t,l,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function ne(n,t){return{point:function(e,r){r=n(e*Ha,r*Ha),e=r[0],t.point(e>La?e-2*La:-La>e?e+2*La:e,r[1])},sphere:function(){t.sphere()},lineStart:function(){t.lineStart()},lineEnd:function(){t.lineEnd()},polygonStart:function(){t.polygonStart()},polygonEnd:function(){t.polygonEnd()}}}function te(n,t){return[n,t]}function ee(n,t,e){return n?t||e?Gt(ie(n),ue(t,e)):ie(n):t||e?ue(t,e):te}function re(n){return function(t,e){return t+=n,[t>La?t-2*La:-La>t?t+2*La:t,e]}}function ie(n){var t=re(n);return t.invert=re(-n),t}function ue(n,t){function e(n,t){var e=Math.cos(t),o=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),f=l*r+o*i;return[Math.atan2(c*u-f*a,o*r-l*i),Math.asin(Math.max(-1,Math.min(1,f*u+c*a)))]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),a=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),o=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),f=l*u-c*a;return[Math.atan2(c*u+l*a,o*r+f*i),Math.asin(Math.max(-1,Math.min(1,f*r-o*i)))]},e}function ae(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,a,o){null!=i?(i=oe(e,i),u=oe(e,u),(a>0?u>i:i>u)&&(i+=2*a*La)):(i=n+2*a*La,u=n);for(var c,l=a*t,f=i;a>0?f>u:u>f;f-=l)o.point((c=Lt([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function oe(n,t){var e=Nt(t);e[0]-=n,Dt(e);var r=Y(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Fa)%(2*Math.PI)}function ce(n,t,e){var r=oa.range(n,t-Fa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function le(n,t,e){var r=oa.range(n,t-Fa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function fe(n){return n.source}function se(n){return n.target}function he(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),a=Math.cos(r),o=Math.sin(r),c=i*Math.cos(n),l=i*Math.sin(n),f=a*Math.cos(e),s=a*Math.sin(e),h=2*Math.asin(Math.sqrt(X(r-t)+i*a*X(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*f,i=e*l+t*s,a=e*u+t*o;return[Math.atan2(i,r)*Pa,Math.atan2(a,Math.sqrt(r*r+i*i))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function ge(){function n(n,i){var u=Math.sin(i*=Ha),a=Math.cos(i),o=Math.abs((n*=Ha)-t),c=Math.cos(o);_o+=Math.atan2(Math.sqrt((o=a*Math.sin(o))*o+(o=r*u-e*a*c)*o),e*u+r*a*c),t=n,e=u,r=a}var t,e,r;wo.point=function(i,u){t=i*Ha,e=Math.sin(u*=Ha),r=Math.cos(u),wo.point=n},wo.lineEnd=function(){wo.point=wo.lineEnd=T}}function pe(n){var t=0,e=La/3,r=Qt(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*La/180,e=n[1]*La/180):[180*(t/La),180*(e/La)]},i}function de(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),a-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),a=Math.sqrt(u)/i;return e.invert=function(n,t){var e=a-t;return[Math.atan2(n,e)/i,Math.asin((u-(n*n+e*e)*i*i)/(2*i))]},e}function me(n,t){var e=n(t[0]),r=n([.5*(t[0][0]+t[1][0]),t[0][1]]),i=n([t[1][0],t[0][1]]),u=n(t[1]),a=r[1]-e[1],o=r[0]-e[0],c=i[1]-r[1],l=i[0]-r[0],f=a/o,s=c/l,h=.5*(f*s*(e[1]-i[1])+s*(e[0]+r[0])-f*(r[0]+i[0]))/(s-f),g=(.5*(e[0]+r[0])-h)/f+.5*(e[1]+r[1]),p=u[0]-h,d=u[1]-g,m=e[0]-h,v=e[1]-g,y=p*p+d*d,M=m*m+v*v,x=Math.atan2(d,p),b=Math.atan2(v,m);return function(t){var e=t[0]-h,r=t[1]-g,i=e*e+r*r,u=Math.atan2(r,e);return i>y&&M>i&&u>x&&b>u?n.invert(t):void 0}}function ve(){function n(n,t){Eo+=i*n-r*t,r=n,i=t}var t,e,r,i;ko.point=function(u,a){ko.point=n,t=r=u,e=i=a},ko.lineEnd=function(){n(t,e)}}function ye(){function n(n,t){a.push("M",n,",",t,u)}function t(n,t){a.push("M",n,",",t),o.point=e}function e(n,t){a.push("L",n,",",t)}function r(){o.point=n}function i(){a.push("Z")}var u=Se(4.5),a=[],o={point:n,lineStart:function(){o.point=t},lineEnd:r,polygonStart:function(){o.lineEnd=i},polygonEnd:function(){o.lineEnd=r,o.point=n},pointRadius:function(n){return u=Se(n),o},result:function(){if(a.length){var n=a.join("");return a=[],n}}};return o}function Me(n,t){go||(mo+=n,vo+=t,++yo)}function xe(){function n(n,r){var i=n-t,u=r-e,a=Math.sqrt(i*i+u*u);mo+=a*(t+n)/2,vo+=a*(e+r)/2,yo+=a,t=n,e=r}var t,e;if(1!==go){if(!(1>go))return;go=1,mo=vo=yo=0}Ao.point=function(r,i){Ao.point=n,t=r,e=i}}function be(){Ao.point=Me}function _e(){function n(n,t){var e=i*n-r*t;mo+=e*(r+n),vo+=e*(i+t),yo+=3*e,r=n,i=t}var t,e,r,i;2>go&&(go=2,mo=vo=yo=0),Ao.point=function(u,a){Ao.point=n,t=r=u,e=i=a},Ao.lineEnd=function(){n(t,e)}}function we(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,a,0,2*La)}function e(t,e){n.moveTo(t,e),o.point=r}function r(t,e){n.lineTo(t,e)}function i(){o.point=t}function u(){n.closePath()}var a=4.5,o={point:t,lineStart:function(){o.point=e},lineEnd:i,polygonStart:function(){o.lineEnd=u},polygonEnd:function(){o.lineEnd=i,o.point=t},pointRadius:function(n){return a=n,o},result:T};return o}function Se(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ee(n){var t=Kt(function(t,e){return n([t*Pa,e*Pa])});return function(n){return n=t(n),{point:function(t,e){n.point(t*Ha,e*Ha)},sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}}function ke(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),a=Math.cos(i);return[Math.atan2(n*u,r*a),Math.asin(r&&e*u/r)]},e}function Ae(n,t){function e(n,t){var e=Math.abs(Math.abs(t)-La/2)<Fa?0:a/Math.pow(i(t),u);return[e*Math.sin(u*n),a-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(La/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),a=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=a-t,r=O(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(a/r,1/u))-La/2]},e):qe}function Ne(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return Math.abs(i)<Fa?te:(e.invert=function(n,t){var e=u-t;return[Math.atan2(n,e)/i,u-O(i)*Math.sqrt(n*n+e*e)]},e)}function qe(n,t){return[n,Math.log(Math.tan(La/4+t/2))]}function Te(n){var t,e=Wt(n),r=e.scale,i=e.translate,u=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=i.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var a=u.apply(e,arguments);if(a===e){if(t=null==n){var o=La*r(),c=i();u([[c[0]-o,c[1]-o],[c[0]+o,c[1]+o]])}}else t&&(a=null);return a},e.clipExtent(null)}function Ce(n,t){var e=Math.cos(t)*Math.sin(n);return[Math.log((1+e)/(1-e))/2,Math.atan2(Math.tan(t),Math.cos(n))]}function ze(n){function t(t){function a(){l.push("M",u(n(f),o))}for(var c,l=[],f=[],s=-1,h=t.length,g=ft(e),p=ft(r);++s<h;)i.call(this,c=t[s],s)?f.push([+g.call(this,c,s),+p.call(this,c,s)]):f.length&&(a(),f=[]);return f.length&&a(),l.length?l.join(""):null}var e=De,r=je,i=jt,u=Le,a=u.key,o=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(i=n,t):i},t.interpolate=function(n){return arguments.length?(a="function"==typeof n?u=n:(u=Do.get(n)||Le).key,t):a},t.tension=function(n){return arguments.length?(o=n,t):o},t}function De(n){return n[0]}function je(n){return n[1]}function Le(n){return n.join("L")}function Fe(n){return Le(n)+"Z"}function He(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("V",(r=n[t])[1],"H",r[0]);return i.join("")}function Pe(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r=n[t])[0],"V",r[1]);return i.join("")}function Re(n,t){return n.length<4?Le(n):n[1]+Ue(n.slice(1,n.length-1),Ie(n,t))}function Oe(n,t){return n.length<3?Le(n):n[0]+Ue((n.push(n[0]),n),Ie([n[n.length-2]].concat(n,[n[1]]),t))}function Ye(n,t){return n.length<3?Le(n):n[0]+Ue(n,Ie(n,t))}function Ue(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return Le(n);var e=n.length!=t.length,r="",i=n[0],u=n[1],a=t[0],o=a,c=1;if(e&&(r+="Q"+(u[0]-a[0]*2/3)+","+(u[1]-a[1]*2/3)+","+u[0]+","+u[1],i=n[1],c=2),t.length>1){o=t[1],u=n[c],c++,r+="C"+(i[0]+a[0])+","+(i[1]+a[1])+","+(u[0]-o[0])+","+(u[1]-o[1])+","+u[0]+","+u[1];for(var l=2;l<t.length;l++,c++)u=n[c],o=t[l],r+="S"+(u[0]-o[0])+","+(u[1]-o[1])+","+u[0]+","+u[1]}if(e){var f=n[c];r+="Q"+(u[0]+o[0]*2/3)+","+(u[1]+o[1]*2/3)+","+f[0]+","+f[1]}return r}function Ie(n,t){for(var e,r=[],i=(1-t)/2,u=n[0],a=n[1],o=1,c=n.length;++o<c;)e=u,u=a,a=n[o],r.push([i*(a[0]-e[0]),i*(a[1]-e[1])]);return r}function Ve(n){if(n.length<3)return Le(n);var t=1,e=n.length,r=n[0],i=r[0],u=r[1],a=[i,i,i,(r=n[1])[0]],o=[u,u,u,r[1]],c=[i,",",u];for(Je(c,a,o);++t<e;)r=n[t],a.shift(),a.push(r[0]),o.shift(),o.push(r[1]),Je(c,a,o);for(t=-1;++t<2;)a.shift(),a.push(r[0]),o.shift(),o.push(r[1]),Je(c,a,o);return c.join("")}function Xe(n){if(n.length<4)return Le(n);for(var t,e=[],r=-1,i=n.length,u=[0],a=[0];++r<3;)t=n[r],u.push(t[0]),a.push(t[1]);for(e.push($e(Fo,u)+","+$e(Fo,a)),--r;++r<i;)t=n[r],u.shift(),u.push(t[0]),a.shift(),a.push(t[1]),Je(e,u,a);return e.join("")}function Ze(n){for(var t,e,r=-1,i=n.length,u=i+4,a=[],o=[];++r<4;)e=n[r%i],a.push(e[0]),o.push(e[1]);for(t=[$e(Fo,a),",",$e(Fo,o)],--r;++r<u;)e=n[r%i],a.shift(),a.push(e[0]),o.shift(),o.push(e[1]),Je(t,a,o);return t.join("")}function Be(n,t){var e=n.length-1;if(e)for(var r,i,u=n[0][0],a=n[0][1],o=n[e][0]-u,c=n[e][1]-a,l=-1;++l<=e;)r=n[l],i=l/e,r[0]=t*r[0]+(1-t)*(u+i*o),r[1]=t*r[1]+(1-t)*(a+i*c);return Ve(n)}function $e(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Je(n,t,e){n.push("C",$e(jo,t),",",$e(jo,e),",",$e(Lo,t),",",$e(Lo,e),",",$e(Fo,t),",",$e(Fo,e))}function Ge(n,t){return(t[1]-n[1])/(t[0]-n[0])}function Ke(n){for(var t=0,e=n.length-1,r=[],i=n[0],u=n[1],a=r[0]=Ge(i,u);++t<e;)r[t]=(a+(a=Ge(i=u,u=n[t+1])))/2;return r[t]=a,r}function We(n){for(var t,e,r,i,u=[],a=Ke(n),o=-1,c=n.length-1;++o<c;)t=Ge(n[o],n[o+1]),Math.abs(t)<1e-6?a[o]=a[o+1]=0:(e=a[o]/t,r=a[o+1]/t,i=e*e+r*r,i>9&&(i=3*t/Math.sqrt(i),a[o]=i*e,a[o+1]=i*r));for(o=-1;++o<=c;)i=(n[Math.min(c,o+1)][0]-n[Math.max(0,o-1)][0])/(6*(1+a[o]*a[o])),u.push([i||0,a[o]*i||0]);return u}function Qe(n){return n.length<3?Le(n):n[0]+Ue(n,We(n))}function nr(n,t,e,r){var i,u,a,o,c,l,f;return i=r[n],u=i[0],a=i[1],i=r[t],o=i[0],c=i[1],i=r[e],l=i[0],f=i[1],(f-a)*(o-u)-(c-a)*(l-u)>0}function tr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])
-}function er(n,t,e,r){var i=n[0],u=e[0],a=t[0]-i,o=r[0]-u,c=n[1],l=e[1],f=t[1]-c,s=r[1]-l,h=(o*(c-l)-s*(i-u))/(s*a-o*f);return[i+h*a,c+h*f]}function rr(n,t){var e={list:n.map(function(n,t){return{index:t,x:n[0],y:n[1]}}).sort(function(n,t){return n.y<t.y?-1:n.y>t.y?1:n.x<t.x?-1:n.x>t.x?1:0}),bottomSite:null},r={list:[],leftEnd:null,rightEnd:null,init:function(){r.leftEnd=r.createHalfEdge(null,"l"),r.rightEnd=r.createHalfEdge(null,"l"),r.leftEnd.r=r.rightEnd,r.rightEnd.l=r.leftEnd,r.list.unshift(r.leftEnd,r.rightEnd)},createHalfEdge:function(n,t){return{edge:n,side:t,vertex:null,l:null,r:null}},insert:function(n,t){t.l=n,t.r=n.r,n.r.l=t,n.r=t},leftBound:function(n){var t=r.leftEnd;do t=t.r;while(t!=r.rightEnd&&i.rightOf(t,n));return t=t.l},del:function(n){n.l.r=n.r,n.r.l=n.l,n.edge=null},right:function(n){return n.r},left:function(n){return n.l},leftRegion:function(n){return n.edge==null?e.bottomSite:n.edge.region[n.side]},rightRegion:function(n){return n.edge==null?e.bottomSite:n.edge.region[Ho[n.side]]}},i={bisect:function(n,t){var e={region:{l:n,r:t},ep:{l:null,r:null}},r=t.x-n.x,i=t.y-n.y,u=r>0?r:-r,a=i>0?i:-i;return e.c=n.x*r+n.y*i+.5*(r*r+i*i),u>a?(e.a=1,e.b=i/r,e.c/=r):(e.b=1,e.a=r/i,e.c/=i),e},intersect:function(n,t){var e=n.edge,r=t.edge;if(!e||!r||e.region.r==r.region.r)return null;var i=e.a*r.b-e.b*r.a;if(Math.abs(i)<1e-10)return null;var u,a,o=(e.c*r.b-r.c*e.b)/i,c=(r.c*e.a-e.c*r.a)/i,l=e.region.r,f=r.region.r;l.y<f.y||l.y==f.y&&l.x<f.x?(u=n,a=e):(u=t,a=r);var s=o>=a.region.r.x;return s&&u.side==="l"||!s&&u.side==="r"?null:{x:o,y:c}},rightOf:function(n,t){var e=n.edge,r=e.region.r,i=t.x>r.x;if(i&&n.side==="l")return 1;if(!i&&n.side==="r")return 0;if(e.a===1){var u=t.y-r.y,a=t.x-r.x,o=0,c=0;if(!i&&e.b<0||i&&e.b>=0?c=o=u>=e.b*a:(c=t.x+t.y*e.b>e.c,e.b<0&&(c=!c),c||(o=1)),!o){var l=r.x-e.region.l.x;c=e.b*(a*a-u*u)<l*u*(1+2*a/l+e.b*e.b),e.b<0&&(c=!c)}}else{var f=e.c-e.a*t.x,s=t.y-f,h=t.x-r.x,g=f-r.y;c=s*s>h*h+g*g}return n.side==="l"?c:!c},endPoint:function(n,e,r){n.ep[e]=r,n.ep[Ho[e]]&&t(n)},distance:function(n,t){var e=n.x-t.x,r=n.y-t.y;return Math.sqrt(e*e+r*r)}},u={list:[],insert:function(n,t,e){n.vertex=t,n.ystar=t.y+e;for(var r=0,i=u.list,a=i.length;a>r;r++){var o=i[r];if(!(n.ystar>o.ystar||n.ystar==o.ystar&&t.x>o.vertex.x))break}i.splice(r,0,n)},del:function(n){for(var t=0,e=u.list,r=e.length;r>t&&e[t]!=n;++t);e.splice(t,1)},empty:function(){return u.list.length===0},nextEvent:function(n){for(var t=0,e=u.list,r=e.length;r>t;++t)if(e[t]==n)return e[t+1];return null},min:function(){var n=u.list[0];return{x:n.vertex.x,y:n.ystar}},extractMin:function(){return u.list.shift()}};r.init(),e.bottomSite=e.list.shift();for(var a,o,c,l,f,s,h,g,p,d,m,v,y,M=e.list.shift();;)if(u.empty()||(a=u.min()),M&&(u.empty()||M.y<a.y||M.y==a.y&&M.x<a.x))o=r.leftBound(M),c=r.right(o),h=r.rightRegion(o),v=i.bisect(h,M),s=r.createHalfEdge(v,"l"),r.insert(o,s),d=i.intersect(o,s),d&&(u.del(o),u.insert(o,d,i.distance(d,M))),o=s,s=r.createHalfEdge(v,"r"),r.insert(o,s),d=i.intersect(s,c),d&&u.insert(s,d,i.distance(d,M)),M=e.list.shift();else{if(u.empty())break;o=u.extractMin(),l=r.left(o),c=r.right(o),f=r.right(c),h=r.leftRegion(o),g=r.rightRegion(c),m=o.vertex,i.endPoint(o.edge,o.side,m),i.endPoint(c.edge,c.side,m),r.del(o),u.del(c),r.del(c),y="l",h.y>g.y&&(p=h,h=g,g=p,y="r"),v=i.bisect(h,g),s=r.createHalfEdge(v,y),r.insert(l,s),i.endPoint(v,Ho[y],m),d=i.intersect(l,s),d&&(u.del(l),u.insert(l,d,i.distance(d,h))),d=i.intersect(s,f),d&&u.insert(s,d,i.distance(d,h))}for(o=r.right(r.leftEnd);o!=r.rightEnd;o=r.right(o))t(o.edge)}function ir(n){return n.x}function ur(n){return n.y}function ar(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function or(n,t,e,r,i,u){if(!n(t,e,r,i,u)){var a=.5*(e+i),o=.5*(r+u),c=t.nodes;c[0]&&or(n,c[0],e,r,a,o),c[1]&&or(n,c[1],a,r,i,o),c[2]&&or(n,c[2],e,o,a,u),c[3]&&or(n,c[3],a,o,i,u)}}function cr(n,t){n=oa.rgb(n),t=oa.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,a=t.g-r,o=t.b-i;return function(n){return"#"+it(Math.round(e+u*n))+it(Math.round(r+a*n))+it(Math.round(i+o*n))}}function lr(n){var t=[n.a,n.b],e=[n.c,n.d],r=sr(t),i=fr(t,e),u=sr(hr(e,t,-i))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,i*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Pa,this.translate=[n.e,n.f],this.scale=[r,u],this.skew=u?Math.atan2(i,u)*Pa:0}function fr(n,t){return n[0]*t[0]+n[1]*t[1]}function sr(n){var t=Math.sqrt(fr(n,n));return t&&(n[0]/=t,n[1]/=t),t}function hr(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function gr(n,t){return t-=n=+n,function(e){return n+t*e}}function pr(n,t){var e,r=[],i=[],u=oa.transform(n),a=oa.transform(t),o=u.translate,c=a.translate,l=u.rotate,f=a.rotate,s=u.skew,h=a.skew,g=u.scale,p=a.scale;return o[0]!=c[0]||o[1]!=c[1]?(r.push("translate(",null,",",null,")"),i.push({i:1,x:gr(o[0],c[0])},{i:3,x:gr(o[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),l!=f?(l-f>180?f+=360:f-l>180&&(l+=360),i.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:gr(l,f)})):f&&r.push(r.pop()+"rotate("+f+")"),s!=h?i.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:gr(s,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),i.push({i:e-4,x:gr(g[0],p[0])},{i:e-2,x:gr(g[1],p[1])})):(p[0]!=1||p[1]!=1)&&r.push(r.pop()+"scale("+p+")"),e=i.length,function(n){for(var t,u=-1;++u<e;)r[(t=i[u]).i]=t.x(n);return r.join("")}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=yr(e)(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function mr(n,t){var e,r,i,u,a,o=0,c=0,l=[],f=[];for(n+="",t+="",Ro.lastIndex=0,r=0;e=Ro.exec(t);++r)e.index&&l.push(t.substring(o,c=e.index)),f.push({i:l.length,x:e[0]}),l.push(null),o=Ro.lastIndex;for(o<t.length&&l.push(t.substring(o)),r=0,u=f.length;(e=Ro.exec(n))&&u>r;++r)if(a=f[r],a.x==e[0]){if(a.i)if(l[a.i+1]==null)for(l[a.i-1]+=a.x,l.splice(a.i,1),i=r+1;u>i;++i)f[i].i--;else for(l[a.i-1]+=a.x+l[a.i+1],l.splice(a.i,2),i=r+1;u>i;++i)f[i].i-=2;else if(l[a.i+1]==null)l[a.i]=a.x;else for(l[a.i]=a.x+l[a.i+1],l.splice(a.i+1,1),i=r+1;u>i;++i)f[i].i--;f.splice(r,1),u--,r--}else a.x=gr(parseFloat(e[0]),parseFloat(a.x));for(;u>r;)a=f.pop(),l[a.i+1]==null?l[a.i]=a.x:(l[a.i]=a.x+l[a.i+1],l.splice(a.i+1,1)),u--;return l.length===1?l[0]==null?f[0].x:function(){return t}:function(n){for(r=0;u>r;++r)l[(a=f[r]).i]=a.x(n);return l.join("")}}function vr(n,t){for(var e,r=oa.interpolators.length;--r>=0&&!(e=oa.interpolators[r](n,t)););return e}function yr(n){return"transform"==n?pr:vr}function Mr(n,t){var e,r=[],i=[],u=n.length,a=t.length,o=Math.min(n.length,t.length);for(e=0;o>e;++e)r.push(vr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;a>e;++e)i[e]=t[e];return function(n){for(e=0;o>e;++e)i[e]=r[e](n);return i}}function xr(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function br(n){return function(t){return 1-n(1-t)}}function _r(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function wr(n){return n*n}function Sr(n){return n*n*n}function Er(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function kr(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*La/2)}function Nr(n){return Math.pow(2,10*(n-1))}function qr(n){return 1-Math.sqrt(1-n*n)}function Tr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/(2*La)*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,10*-r)*Math.sin(2*(r-e)*La/t)}}function Cr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function zr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Dr(n,t){n=oa.hcl(n),t=oa.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,a=t.c-r,o=t.l-i;return isNaN(a)&&(a=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return $(e+u*n,r+a*n,i+o*n)+""}}function jr(n,t){n=oa.hsl(n),t=oa.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,a=t.s-r,o=t.l-i;return isNaN(a)&&(a=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return R(e+u*n,r+a*n,i+o*n)+""}}function Lr(n,t){n=oa.lab(n),t=oa.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,a=t.a-r,o=t.b-i;return function(n){return K(e+u*n,r+a*n,i+o*n)+""}}function Fr(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Hr(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pr(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Rr(n){for(var t=n.source,e=n.target,r=Yr(t,e),i=[t];t!==r;)t=t.parent,i.push(t);for(var u=i.length;e!==r;)i.splice(u,0,e),e=e.parent;return i}function Or(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Yr(n,t){if(n===t)return n;for(var e=Or(n),r=Or(t),i=e.pop(),u=r.pop(),a=null;i===u;)a=i,i=e.pop(),u=r.pop();return a}function Ur(n){n.fixed|=2}function Ir(n){n.fixed&=-7}function Vr(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Xr(n){n.fixed&=-5}function Zr(n,t,e){var r=0,i=0;if(n.charge=0,!n.leaf)for(var u,a=n.nodes,o=a.length,c=-1;++c<o;)u=a[c],null!=u&&(Zr(u,t,e),n.charge+=u.charge,r+=u.charge*u.cx,i+=u.charge*u.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var l=t*e[n.point.index];n.charge+=n.pointCharge=l,r+=l*n.point.x,i+=l*n.point.y}n.cx=r/n.charge,n.cy=i/n.charge}function Br(n,t){return oa.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Kr,n}function $r(n){return n.children}function Jr(n){return n.value}function Gr(n,t){return t.value-n.value}function Kr(n){return oa.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Wr(n){return n.x}function Qr(n){return n.y}function ni(n,t,e){n.y0=t,n.y=e}function ti(n){return oa.range(n.length)}function ei(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ri(n){for(var t,e=1,r=0,i=n[0][1],u=n.length;u>e;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function ii(n){return n.reduce(ui,0)}function ui(n,t){return n+t[1]}function ai(n,t){return oi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function oi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function ci(n){return[oa.min(n),oa.max(n)]}function li(n,t){return n.parent==t.parent?1:2}function fi(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function hi(n,t){var e=n.children;if(e&&(i=e.length))for(var r,i,u=-1;++u<i;)t(r=hi(e[u],t),n)>0&&(n=r);return n}function gi(n,t){return n.x-t.x}function pi(n,t){return t.x-n.x}function di(n,t){return n.depth-t.depth}function mi(n,t){function e(n,r){var i=n.children;if(i&&(a=i.length))for(var u,a,o=null,c=-1;++c<a;)u=i[c],e(u,o),o=u;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,i=n.children,u=i.length;--u>=0;)t=i[u]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function yi(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function Mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function xi(n,t){return n.value-t.value}function bi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function _i(n,t){n._pack_next=t,t._pack_prev=n}function wi(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return i*i-e*e-r*r>.001}function Si(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,i,u,a,o,c,l,f=1/0,s=-1/0,h=1/0,g=-1/0;if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(i=e[1],i.x=i.r,i.y=0,t(i),l>2))for(u=e[2],Ni(r,i,u),t(u),bi(r,u),r._pack_prev=u,bi(u,i),i=r._pack_next,a=3;l>a;a++){Ni(r,i,u=e[a]);var p=0,d=1,m=1;for(o=i._pack_next;o!==i;o=o._pack_next,d++)if(wi(o,u)){p=1;break}if(1==p)for(c=r._pack_prev;c!==o._pack_prev&&!wi(c,u);c=c._pack_prev,m++);p?(m>d||d==m&&i.r<r.r?_i(r,i=o):_i(r=c,i),a--):(bi(r,u),i=u,t(u))}var v=(f+s)/2,y=(h+g)/2,M=0;for(a=0;l>a;a++)u=e[a],u.x-=v,u.y-=y,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(ki)}}function Ei(n){n._pack_next=n._pack_prev=n}function ki(n){delete n._pack_next,delete n._pack_prev}function Ai(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,a=i.length;++u<a;)Ai(i[u],t,e,r)}function Ni(n,t,e){var r=n.r+e.r,i=t.x-n.x,u=t.y-n.y;if(r&&(i||u)){var a=t.r+e.r,o=i*i+u*u;a*=a,r*=r;var c=.5+(r-a)/(2*o),l=Math.sqrt(Math.max(0,2*a*(r+o)-(r-=o)*r-a*a))/(2*o);e.x=n.x+c*i+l*u,e.y=n.y+c*u-l*i}else e.x=n.x+r,e.y=n.y}function qi(n){return 1+oa.max(n,function(n){return n.y})}function Ti(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ci(n){var t=n.children;return t&&t.length?Ci(t[0]):n}function zi(n){var t,e=n.children;return e&&(t=e.length)?zi(e[t-1]):n}function Di(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function ji(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Li(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Fi(n){return n.rangeExtent?n.rangeExtent():Li(n.range())}function Hi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Pi(n,t){var e,r=0,i=n.length-1,u=n[r],a=n[i];return u>a&&(e=r,r=i,i=e,e=u,u=a,a=e),(t=t(a-u))&&(n[r]=t.floor(u),n[i]=t.ceil(a)),n}function Ri(n,t,e,r){var i=[],u=[],a=0,o=Math.min(n.length,t.length)-1;for(n[o]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++a<=o;)i.push(e(n[a-1],n[a])),u.push(r(t[a-1],t[a]));return function(t){var e=oa.bisect(n,t,1,o)-1;return u[e](i[e](t))}}function Oi(n,t,e,r){function i(){var i=Math.min(n.length,t.length)>2?Ri:Hi,c=r?Pr:Hr;return a=i(n,t,c,e),o=i(t,n,c,vr),u}function u(n){return a(n)}var a,o;return u.invert=function(n){return o(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Fr)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Vi(n,t)},u.tickFormat=function(t,e){return Xi(n,t,e)},u.nice=function(){return Pi(n,Ui),i()},u.copy=function(){return Oi(n,t,e,r)},i()}function Yi(n,t){return oa.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Ui(n){return n=Math.pow(10,Math.round(Math.log(n)/Math.LN10)-1),n&&{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}}function Ii(n,t){var e=Li(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Vi(n,t){return oa.range.apply(oa,Ii(n,t))}function Xi(n,t,e){var r=-Math.floor(Math.log(Ii(n,t)[2])/Math.LN10+.01);return oa.format(e?e.replace(ro,function(n,t,e,i,u,a,o,c,l,f){return[t,e,i,u,a,o,c,l||"."+(r-2*("%"===f)),f].join("")}):",."+r+"f")}function Zi(n,t,e,r){function i(t){return n(e(t))}return i.invert=function(t){return r(n.invert(t))},i.domain=function(t){return arguments.length?(t[0]<0?(e=Ji,r=Gi):(e=Bi,r=$i),n.domain(t.map(e)),i):n.domain().map(r)},i.base=function(n){return arguments.length?(t=+n,i):t},i.nice=function(){return n.domain(Pi(n.domain(),Ki(t))),i},i.ticks=function(){var i=Li(n.domain()),u=[];if(i.every(isFinite)){var a=Math.log(t),o=Math.floor(i[0]/a),c=Math.ceil(i[1]/a),l=r(i[0]),f=r(i[1]),s=t%1?2:t;if(e===Ji)for(u.push(-Math.pow(t,-o));o++<c;)for(var h=s-1;h>0;h--)u.push(-Math.pow(t,-o)*h);else{for(;c>o;o++)for(var h=1;s>h;h++)u.push(Math.pow(t,o)*h);u.push(Math.pow(t,o))}for(o=0;u[o]<l;o++);for(c=u.length;u[c-1]>f;c--);u=u.slice(o,c)}return u},i.tickFormat=function(n,u){if(arguments.length<2&&(u=$o),!arguments.length)return u;var a,o=Math.log(t),c=Math.max(.1,n/i.ticks().length),l=e===Ji?(a=-1e-12,Math.floor):(a=1e-12,Math.ceil);return function(n){return n/r(o*l(e(n)/o+a))<=c?u(n):""}},i.copy=function(){return Zi(n.copy(),t,e,r)},Yi(i,n)}function Bi(n){return Math.log(0>n?0:n)}function $i(n){return Math.exp(n)}function Ji(n){return-Math.log(n>0?0:-n)}function Gi(n){return-Math.exp(-n)}function Ki(n){n=Math.log(n);var t={floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}};return function(){return t}}function Wi(n,t){function e(t){return n(r(t))}var r=Qi(t),i=Qi(1/t);return e.invert=function(t){return i(n.invert(t))},e.domain=function(t){return arguments.length?(n.domain(t.map(r)),e):n.domain().map(i)},e.ticks=function(n){return Vi(e.domain(),n)},e.tickFormat=function(n,t){return Xi(e.domain(),n,t)},e.nice=function(){return e.domain(Pi(e.domain(),Ui))},e.exponent=function(n){if(!arguments.length)return t;var u=e.domain();return r=Qi(t=n),i=Qi(1/t),e.domain(u)},e.copy=function(){return Wi(n.copy(),t)},Yi(e,n)}function Qi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function nu(n,t){function e(t){return a[((u.get(t)||u.set(t,n.push(t)))-1)%a.length]}function r(t,e){return oa.range(n.length).map(function(n){return t+e*n})}var u,a,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new i;for(var a,o=-1,c=r.length;++o<c;)u.has(a=r[o])||u.set(a,n.push(a));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(a=n,o=0,t={t:"range",a:arguments},e):a},e.rangePoints=function(i,u){arguments.length<2&&(u=0);var c=i[0],l=i[1],f=(l-c)/(Math.max(1,n.length-1)+u);return a=r(n.length<2?(c+l)/2:c+f*u/2,f),o=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(i,u,c){arguments.length<2&&(u=0),arguments.length<3&&(c=u);var l=i[1]<i[0],f=i[l-0],s=i[1-l],h=(s-f)/(n.length-u+2*c);return a=r(f+h*c,h),l&&a.reverse(),o=h*(1-u),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(i,u,c){arguments.length<2&&(u=0),arguments.length<3&&(c=u);var l=i[1]<i[0],f=i[l-0],s=i[1-l],h=Math.floor((s-f)/(n.length-u+2*c)),g=s-f-(n.length-u)*h;return a=r(f+Math.round(g/2),h),l&&a.reverse(),o=Math.round(h*(1-u)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Li(t.a[0])},e.copy=function(){return nu(n,t)},e.domain(n)}function tu(n,t){function e(){var e=0,u=t.length;for(i=[];++e<u;)i[e-1]=oa.quantile(n,e/u);return r}function r(n){return isNaN(n=+n)?0/0:t[oa.bisect(i,n)]}var i;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(oa.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return i},r.copy=function(){return tu(n,t)},e()}function eu(n,t,e){function r(t){return e[Math.max(0,Math.min(a,Math.floor(u*(t-n))))]}function i(){return u=e.length/(t-n),a=e.length-1,r}var u,a;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],i()):[n,t]},r.range=function(n){return arguments.length?(e=n,i()):e},r.copy=function(){return eu(n,t,e)},i()}function ru(n,t){function e(e){return t[oa.bisect(n,e)]}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.copy=function(){return ru(n,t)},e}function iu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Vi(n,t)},t.tickFormat=function(t,e){return Xi(n,t,e)},t.copy=function(){return iu(n)},t}function uu(n){return n.innerRadius}function au(n){return n.outerRadius}function ou(n){return n.startAngle}function cu(n){return n.endAngle}function lu(n){for(var t,e,r,i=-1,u=n.length;++i<u;)t=n[i],e=t[0],r=t[1]+Qo,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function fu(n){function t(t){function c(){d.push("M",o(n(v),s),f,l(n(m.reverse()),s),"Z")}for(var h,g,p,d=[],m=[],v=[],y=-1,M=t.length,x=ft(e),b=ft(i),_=e===r?function(){return g}:ft(r),w=i===u?function(){return p}:ft(u);++y<M;)a.call(this,h=t[y],y)?(m.push([g=+x.call(this,h,y),p=+b.call(this,h,y)]),v.push([+_.call(this,h,y),+w.call(this,h,y)])):m.length&&(c(),m=[],v=[]);return m.length&&c(),d.length?d.join(""):null}var e=De,r=De,i=0,u=je,a=jt,o=Le,c=o.key,l=o,f="L",s=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(i=u=n,t):u},t.y0=function(n){return arguments.length?(i=n,t):i},t.y1=function(n){return arguments.length?(u=n,t):u},t.defined=function(n){return arguments.length?(a=n,t):a},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?o=n:(o=Do.get(n)||Le).key,l=o.reverse||o,f=o.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(s=n,t):s},t}function su(n){return n.radius}function hu(n){return[n.x,n.y]}function gu(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+Qo;return[e*Math.cos(r),e*Math.sin(r)]}}function pu(){return 64}function du(){return"circle"}function mu(n){var t=Math.sqrt(n/La);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function vu(n,t){return Ma(n,uc),n.id=t,n}function yu(n,t,e,r){var i=n.id;return j(n,"function"==typeof e?function(n,u,a){n.__transition__[i].tween.set(t,r(e.call(n,n.__data__,u,a)))}:(e=r(e),function(n){n.__transition__[i].tween.set(t,e)}))}function Mu(n){return null==n&&(n=""),function(){this.textContent=n}}function xu(n,t,e,r){var u=n.__transition__||(n.__transition__={active:0,count:0}),a=u[e];if(!a){var o=r.time;return a=u[e]={tween:new i,event:oa.dispatch("start","end"),time:o,ease:r.ease,delay:r.delay,duration:r.duration},++u.count,oa.timer(function(r){function i(r){return u.active>e?l():(u.active=e,h.start.call(n,f,t),a.tween.forEach(function(e,r){(r=r.call(n,f,t))&&d.push(r)}),c(r)||oa.timer(c,0,o),1)}function c(r){if(u.active!==e)return l();for(var i=(r-g)/p,a=s(i),o=d.length;o>0;)d[--o].call(n,a);return i>=1?(l(),h.end.call(n,f,t),1):void 0}function l(){return--u.count?delete u[e]:delete n.__transition__,1}var f=n.__data__,s=a.ease,h=a.event,g=a.delay,p=a.duration,d=[];return r>=g?i(r):oa.timer(i,g,o),1},0,o),a}}function bu(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function _u(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function wu(n,t,e){if(r=[],e&&t.length>1){for(var r,i,u,a=Li(n.domain()),o=-1,c=t.length,l=(t[1]-t[0])/++e;++o<c;)for(i=e;--i>0;)(u=+t[o]-i*l)>=a[0]&&r.push(u);for(--o,i=0;++i<e&&(u=+t[o]+i*l)<a[1];)r.push(u)}return r}function Su(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Eu(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new hc(e-1)),1),e}function u(n,e){return t(n=new hc(+n),e),n}function a(n,r,u){var a=i(n),o=[];if(u>1)for(;r>a;)e(a)%u||o.push(new Date(+a)),t(a,1);else for(;r>a;)o.push(new Date(+a)),t(a,1);return o}function o(n,t,e){try{hc=Su;var r=new Su;return r._=n,a(r,t,e)}finally{hc=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=a;var c=n.utc=ku(n);return c.floor=c,c.round=ku(r),c.ceil=ku(i),c.offset=ku(u),c.range=o,n}function ku(n){return function(t,e){try{hc=Su;var r=new Su;return r._=t,n(r,e)._}finally{hc=Date}}}function Au(n,t,e,r){for(var i,u,a=0,o=t.length,c=e.length;o>a;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(u=Tc[t.charAt(a++)],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function Nu(n){return RegExp("^(?:"+n.map(oa.requote).join("|")+")","i")}function qu(n){for(var t=new i,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Tu(n,t,e){n+="";var r=n.length;return e>r?Array(e-r+1).join(t)+n:n}function Cu(n,t,e){wc.lastIndex=0;var r=wc.exec(t.substring(e));return r?e+=r[0].length:-1}function zu(n,t,e){_c.lastIndex=0;var r=_c.exec(t.substring(e));return r?e+=r[0].length:-1}function Du(n,t,e){kc.lastIndex=0;var r=kc.exec(t.substring(e));return r?(n.m=Ac.get(r[0].toLowerCase()),e+=r[0].length):-1}function ju(n,t,e){Sc.lastIndex=0;var r=Sc.exec(t.substring(e));return r?(n.m=Ec.get(r[0].toLowerCase()),e+=r[0].length):-1}function Lu(n,t,e){return Au(n,""+qc.c,t,e)}function Fu(n,t,e){return Au(n,""+qc.x,t,e)}function Hu(n,t,e){return Au(n,""+qc.X,t,e)}function Pu(n,t,e){Cc.lastIndex=0;var r=Cc.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+=r[0].length):-1}function Ru(n,t,e){Cc.lastIndex=0;var r=Cc.exec(t.substring(e,e+2));return r?(n.y=Ou(+r[0]),e+=r[0].length):-1}function Ou(n){return n+(n>68?1900:2e3)}function Yu(n,t,e){Cc.lastIndex=0;var r=Cc.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+=r[0].length):-1}function Uu(n,t,e){Cc.lastIndex=0;var r=Cc.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+=r[0].length):-1}function Iu(n,t,e){Cc.lastIndex=0;var r=Cc.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+=r[0].length):-1}function Vu(n,t,e){Cc.lastIndex=0;var r=Cc.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+=r[0].length):-1}function Xu(n,t,e){Cc.lastIndex=0;var r=Cc.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+=r[0].length):-1}function Zu(n,t,e){Cc.lastIndex=0;var r=Cc.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+=r[0].length):-1}function Bu(n,t,e){var r=zc.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}function $u(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(Math.abs(t)/60),i=Math.abs(t)%60;return e+Tu(r,"0",2)+Tu(i,"0",2)}function Ju(n){return n.toISOString()}function Gu(n,t,e){function r(t){return n(t)}return r.invert=function(t){return Ku(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Ku)},r.nice=function(n){return r.domain(Pi(r.domain(),function(){return n}))},r.ticks=function(e,i){var u=Li(r.domain());if("function"!=typeof e){var a=u[1]-u[0],o=a/e,c=oa.bisect(jc,o);if(c==jc.length)return t.year(u,e);if(!c)return n.ticks(e).map(Ku);Math.log(o/jc[c-1])<Math.log(jc[c]/o)&&--c,e=t[c],i=e[1],e=e[0].range}return e(u[0],new Date(+u[1]+1),i)},r.tickFormat=function(){return e},r.copy=function(){return Gu(n.copy(),t,e)},Yi(r,n)}function Ku(n){return new Date(n)}function Wu(n){return function(t){for(var e=n.length-1,r=n[e];!r[1](t);)r=n[--e];return r[0](t)}}function Qu(n){var t=new Date(n,0,1);return t.setFullYear(n),t}function na(n){var t=n.getFullYear(),e=Qu(t),r=Qu(t+1);return t+(n-e)/(r-e)}function ta(n){var t=new Date(Date.UTC(n,0,1));return t.setUTCFullYear(n),t}function ea(n){var t=n.getUTCFullYear(),e=ta(t),r=ta(t+1);return t+(n-e)/(r-e)}function ra(n){return n.responseText}function ia(n){return JSON.parse(n.responseText)}function ua(n){var t=ca.createRange();return t.selectNode(ca.body),t.createContextualFragment(n.responseText)}function aa(n){return n.responseXML}var oa={version:"3.1.6"};Date.now||(Date.now=function(){return+new Date});var ca=document,la=window;try{ca.createElement("div").style.setProperty("opacity",0,"")}catch(fa){var sa=la.CSSStyleDeclaration.prototype,ha=sa.setProperty;sa.setProperty=function(n,t,e){ha.call(this,n,t+"",e)}}oa.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},oa.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},oa.min=function(n,t){var e,r,i=-1,u=n.length;if(arguments.length===1){for(;++i<u&&((e=n[i])==null||e!=e);)e=void 0;for(;++i<u;)(r=n[i])!=null&&e>r&&(e=r)}else{for(;++i<u&&((e=t.call(n,n[i],i))==null||e!=e);)e=void 0;for(;++i<u;)(r=t.call(n,n[i],i))!=null&&e>r&&(e=r)}return e},oa.max=function(n,t){var e,r,i=-1,u=n.length;if(arguments.length===1){for(;++i<u&&((e=n[i])==null||e!=e);)e=void 0;for(;++i<u;)(r=n[i])!=null&&r>e&&(e=r)}else{for(;++i<u&&((e=t.call(n,n[i],i))==null||e!=e);)e=void 0;for(;++i<u;)(r=t.call(n,n[i],i))!=null&&r>e&&(e=r)}return e},oa.extent=function(n,t){var e,r,i,u=-1,a=n.length;if(arguments.length===1){for(;++u<a&&((e=i=n[u])==null||e!=e);)e=i=void 0;for(;++u<a;)(r=n[u])!=null&&(e>r&&(e=r),r>i&&(i=r))}else{for(;++u<a&&((e=i=t.call(n,n[u],u))==null||e!=e);)e=void 0;for(;++u<a;)(r=t.call(n,n[u],u))!=null&&(e>r&&(e=r),r>i&&(i=r))}return[e,i]},oa.sum=function(n,t){var e,r=0,i=n.length,u=-1;if(arguments.length===1)for(;++u<i;)isNaN(e=+n[u])||(r+=e);else for(;++u<i;)isNaN(e=+t.call(n,n[u],u))||(r+=e);return r},oa.mean=function(t,e){var r,i=t.length,u=0,a=-1,o=0;if(arguments.length===1)for(;++a<i;)n(r=t[a])&&(u+=(r-u)/++o);else for(;++a<i;)n(r=e.call(t,t[a],a))&&(u+=(r-u)/++o);return o?u:void 0},oa.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),i=+n[r-1],u=e-r;return u?i+u*(n[r]-i):i},oa.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?oa.quantile(t.sort(oa.ascending),.5):void 0},oa.bisector=function(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n.call(t,t[u],u)<e?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;e<n.call(t,t[u],u)?i=u:r=u+1}return r}}};var ga=oa.bisector(function(n){return n});oa.bisectLeft=ga.left,oa.bisect=oa.bisectRight=ga.right,oa.shuffle=function(n){for(var t,e,r=n.length;r;)e=Math.random()*r--|0,t=n[r],n[r]=n[e],n[e]=t;return n},oa.permute=function(n,t){for(var e=[],r=-1,i=t.length;++r<i;)e[r]=n[t[r]];return e},oa.zip=function(){if(!(i=arguments.length))return[];for(var n=-1,e=oa.min(arguments,t),r=Array(e);++n<e;)for(var i,u=-1,a=r[n]=Array(i);++u<i;)a[u]=arguments[u][n];return r},oa.transpose=function(n){return oa.zip.apply(oa,n)},oa.keys=function(n){var t=[];for(var e in n)t.push(e);return t},oa.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},oa.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},oa.merge=function(n){return Array.prototype.concat.apply([],n)},oa.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw Error("infinite range");var i,u=[],a=e(Math.abs(r)),o=-1;if(n*=a,t*=a,r*=a,0>r)for(;(i=n+r*++o)>t;)u.push(i/a);else for(;(i=n+r*++o)<t;)u.push(i/a);return u},oa.map=function(n){var t=new i;for(var e in n)t.set(e,n[e]);return t},r(i,{has:function(n){return pa+n in this},get:function(n){return this[pa+n]},set:function(n,t){return this[pa+n]=t},remove:function(n){return n=pa+n,n in this&&delete this[n]},keys:function(){var n=[];return this.forEach(function(t){n.push(t)}),n},values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},forEach:function(n){for(var t in this)t.charCodeAt(0)===da&&n.call(this,t.substring(1),this[t])}});var pa="\0",da=pa.charCodeAt(0);oa.nest=function(){function n(t,o,c){if(c>=a.length)return r?r.call(u,o):e?o.sort(e):o;for(var l,f,s,h,g=-1,p=o.length,d=a[c++],m=new i;++g<p;)(h=m.get(l=d(f=o[g])))?h.push(f):m.set(l,[f]);return t?(f=t(),s=function(e,r){f.set(e,n(t,r,c))}):(f={},s=function(e,r){f[e]=n(t,r,c)}),m.forEach(s),f}function t(n,e){if(e>=a.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,u={},a=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(oa.map,e,0),0)},u.key=function(n){return a.push(n),u},u.sortKeys=function(n){return o[a.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},oa.set=function(n){var t=new u;if(n)for(var e=0;e<n.length;e++)t.add(n[e]);return t},r(u,{has:function(n){return pa+n in this},add:function(n){return this[pa+n]=!0,n},remove:function(n){return n=pa+n,n in this&&delete this[n]},values:function(){var n=[];return this.forEach(function(t){n.push(t)}),n},forEach:function(n){for(var t in this)t.charCodeAt(0)===da&&n.call(this,t.substring(1))}}),oa.behavior={},oa.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r<i;)n[e=arguments[r]]=a(n,t,t[e]);return n},oa.dispatch=function(){for(var n=new o,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=c(n);return n},o.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(arguments.length===2){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);
-return this}},oa.event=null,oa.mouse=function(n){return g(n,f())};var ma=/WebKit/.test(la.navigator.userAgent)?-1:0,va=d;try{va(ca.documentElement.childNodes)[0].nodeType}catch(ya){va=p}var Ma=[].__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]};oa.touches=function(n,t){return arguments.length<2&&(t=f().touches),t?va(t).map(function(t){var e=g(n,t);return e.identifier=t.identifier,e}):[]},oa.behavior.drag=function(){function n(){this.on("mousedown.drag",t).on("touchstart.drag",t)}function t(){function n(){var n=a.parentNode;return null!=f?oa.touches(n).filter(function(n){return n.identifier===f})[0]:oa.mouse(n)}function t(){if(!a.parentNode)return i();var t=n(),e=t[0]-h[0],r=t[1]-h[1];g|=e|r,h=t,l(),o({type:"drag",x:t[0]+u[0],y:t[1]+u[1],dx:e,dy:r})}function i(){o({type:"dragend"}),g&&(l(),oa.event.target===c&&s(p,"click")),p.on(null!=f?"touchmove.drag-"+f:"mousemove.drag",null).on(null!=f?"touchend.drag-"+f:"mouseup.drag",null)}var u,a=this,o=e.of(a,arguments),c=oa.event.target,f=oa.event.touches?oa.event.changedTouches[0].identifier:null,h=n(),g=0,p=oa.select(la).on(null!=f?"touchmove.drag-"+f:"mousemove.drag",t).on(null!=f?"touchend.drag-"+f:"mouseup.drag",i,!0);r?(u=r.apply(a,arguments),u=[u.x-h[0],u.y-h[1]]):u=[0,0],null==f&&l(),o({type:"dragstart"})}var e=h(n,"drag","dragstart","dragend"),r=null;return n.origin=function(t){return arguments.length?(r=t,n):r},oa.rebind(n,e,"on")};var xa=function(n,t){return t.querySelector(n)},ba=function(n,t){return t.querySelectorAll(n)},_a=ca.documentElement,wa=_a.matchesSelector||_a.webkitMatchesSelector||_a.mozMatchesSelector||_a.msMatchesSelector||_a.oMatchesSelector,Sa=function(n,t){return wa.call(n,t)};"function"==typeof Sizzle&&(xa=function(n,t){return Sizzle(n,t)[0]||null},ba=function(n,t){return Sizzle.uniqueSort(Sizzle(n,t))},Sa=Sizzle.matchesSelector),oa.selection=function(){return Ta};var Ea=oa.selection.prototype=[];Ea.select=function(n){var t,e,r,i,u=[];"function"!=typeof n&&(n=v(n));for(var a=-1,o=this.length;++a<o;){u.push(t=[]),t.parentNode=(r=this[a]).parentNode;for(var c=-1,l=r.length;++c<l;)(i=r[c])?(t.push(e=n.call(i,i.__data__,c)),e&&"__data__"in i&&(e.__data__=i.__data__)):t.push(null)}return m(u)},Ea.selectAll=function(n){var t,e,r=[];"function"!=typeof n&&(n=y(n));for(var i=-1,u=this.length;++i<u;)for(var a=this[i],o=-1,c=a.length;++o<c;)(e=a[o])&&(r.push(t=va(n.call(e,e.__data__,o))),t.parentNode=e);return m(r)};var ka={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};oa.ns={prefix:ka,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ka.hasOwnProperty(e)?{space:ka[e],local:n}:n}},Ea.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=oa.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(M(t,n[t]));return this}return this.each(M(n,t))},oa.requote=function(n){return n.replace(Aa,"\\$&")};var Aa=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;Ea.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=n.trim().split(/^|\s+/g)).length,i=-1;if(t=e.classList){for(;++i<r;)if(!t.contains(n[i]))return!1}else for(t=e.getAttribute("class");++i<r;)if(!_(n[i]).test(t))return!1;return!0}for(t in n)this.each(w(t,n[t]));return this}return this.each(w(n,t))},Ea.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(E(e,n[e],t));return this}if(2>r)return la.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(E(n,t,e))},Ea.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(k(t,n[t]));return this}return this.each(k(n,t))},Ea.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Ea.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Ea.append=function(n){function t(){return this.appendChild(ca.createElementNS(this.namespaceURI,n))}function e(){return this.appendChild(ca.createElementNS(n.space,n.local))}return n=oa.ns.qualify(n),this.select(n.local?e:t)},Ea.insert=function(n,t){function e(e,r){return this.insertBefore(ca.createElementNS(this.namespaceURI,n),t.call(this,e,r))}function r(e,r){return this.insertBefore(ca.createElementNS(n.space,n.local),t.call(this,e,r))}return n=oa.ns.qualify(n),"function"!=typeof t&&(t=v(t)),this.select(n.local?r:e)},Ea.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},Ea.data=function(n,t){function e(n,e){var r,u,a,o=n.length,s=e.length,h=Math.min(o,s),g=Array(s),p=Array(s),d=Array(o);if(t){var m,v=new i,y=new i,M=[];for(r=-1;++r<o;)m=t.call(u=n[r],u.__data__,r),v.has(m)?d[r]=u:v.set(m,u),M.push(m);for(r=-1;++r<s;)m=t.call(e,a=e[r],r),(u=v.get(m))?(g[r]=u,u.__data__=a):y.has(m)||(p[r]=A(a)),y.set(m,a),v.remove(m);for(r=-1;++r<o;)v.has(M[r])&&(d[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],a=e[r],u?(u.__data__=a,g[r]=u):p[r]=A(a);for(;s>r;++r)p[r]=A(e[r]);for(;o>r;++r)d[r]=n[r]}p.update=g,p.parentNode=g.parentNode=d.parentNode=n.parentNode,c.push(p),l.push(g),f.push(d)}var r,u,a=-1,o=this.length;if(!arguments.length){for(n=Array(o=(r=this[0]).length);++a<o;)(u=r[a])&&(n[a]=u.__data__);return n}var c=L([]),l=m([]),f=m([]);if("function"==typeof n)for(;++a<o;)e(r=this[a],n.call(r,r.parentNode.__data__,a));else for(;++a<o;)e(r=this[a],n);return l.enter=function(){return c},l.exit=function(){return f},l},Ea.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},Ea.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=N(n));for(var u=0,a=this.length;a>u;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var o=0,c=e.length;c>o;o++)(r=e[o])&&n.call(r,r.__data__,o)&&t.push(r)}return m(i)},Ea.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],i=r.length-1,u=r[i];--i>=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Ea.sort=function(n){n=q.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},Ea.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(C(n,t,e))};var Na=oa.map({mouseenter:"mouseover",mouseleave:"mouseout"});Na.forEach(function(n){"on"+n in ca&&Na.remove(n)}),Ea.each=function(n){return j(this,function(t,e,r){n.call(t,t.__data__,e,r)})},Ea.call=function(n){var t=va(arguments);return n.apply(t[0]=this,t),this},Ea.empty=function(){return!this.node()},Ea.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null};var qa=[];oa.selection.enter=L,oa.selection.enter.prototype=qa,qa.append=Ea.append,qa.insert=Ea.insert,qa.empty=Ea.empty,qa.node=Ea.node,qa.select=function(n){for(var t,e,r,i,u,a=[],o=-1,c=this.length;++o<c;){r=(i=this[o]).update,a.push(t=[]),t.parentNode=i.parentNode;for(var l=-1,f=i.length;++l<f;)(u=i[l])?(t.push(r[l]=e=n.call(i.parentNode,u.__data__,l)),e.__data__=u.__data__):t.push(null)}return m(a)},Ea.transition=function(){var n,t,e=ec||++ac,r=[],i=Object.create(oc);i.time=Date.now();for(var u=-1,a=this.length;++u<a;){r.push(n=[]);for(var o=this[u],c=-1,l=o.length;++c<l;)(t=o[c])&&xu(t,c,e,i),n.push(t)}return vu(r,e)},oa.select=function(n){var t=["string"==typeof n?xa(n,ca):n];return t.parentNode=_a,m([t])},oa.selectAll=function(n){var t=va("string"==typeof n?ba(n,ca):n);return t.parentNode=_a,m([t])};var Ta=oa.select(_a);oa.behavior.zoom=function(){function n(){this.on("mousedown.zoom",o).on("mousemove.zoom",f).on(Da+".zoom",c).on("dblclick.zoom",g).on("touchstart.zoom",p).on("touchmove.zoom",d).on("touchend.zoom",p)}function t(n){return[(n[0]-w[0])/S,(n[1]-w[1])/S]}function e(n){return[n[0]*S+w[0],n[1]*S+w[1]]}function r(n){S=Math.max(E[0],Math.min(E[1],n))}function i(n,t){t=e(t),w[0]+=n[0]-t[0],w[1]+=n[1]-t[1]}function u(){M&&M.domain(y.range().map(function(n){return(n-w[0])/S}).map(y.invert)),b&&b.domain(x.range().map(function(n){return(n-w[1])/S}).map(x.invert))}function a(n){u(),oa.event.preventDefault(),n({type:"zoom",scale:S,translate:w})}function o(){function n(){c=1,i(oa.mouse(r),h),a(u)}function e(){c&&l(),f.on("mousemove.zoom",null).on("mouseup.zoom",null),c&&oa.event.target===o&&s(f,"click.zoom")}var r=this,u=k.of(r,arguments),o=oa.event.target,c=0,f=oa.select(la).on("mousemove.zoom",n).on("mouseup.zoom",e),h=t(oa.mouse(r));la.focus(),l()}function c(){m||(m=t(oa.mouse(this))),r(Math.pow(2,Ca()*.002)*S),i(oa.mouse(this),m),a(k.of(this,arguments))}function f(){m=null}function g(){var n=oa.mouse(this),e=t(n),u=Math.log(S)/Math.LN2;r(Math.pow(2,oa.event.shiftKey?Math.ceil(u)-1:Math.floor(u)+1)),i(n,e),a(k.of(this,arguments))}function p(){var n=oa.touches(this),e=Date.now();if(v=S,m={},n.forEach(function(n){m[n.identifier]=t(n)}),l(),n.length===1){if(500>e-_){var u=n[0],o=t(n[0]);r(2*S),i(u,o),a(k.of(this,arguments))}_=e}}function d(){var n=oa.touches(this),t=n[0],e=m[t.identifier];if(u=n[1]){var u,o=m[u.identifier];t=[(t[0]+u[0])/2,(t[1]+u[1])/2],e=[(e[0]+o[0])/2,(e[1]+o[1])/2],r(oa.event.scale*v)}i(t,e),_=null,a(k.of(this,arguments))}var m,v,y,M,x,b,_,w=[0,0],S=1,E=za,k=h(n,"zoom");return n.translate=function(t){return arguments.length?(w=t.map(Number),u(),n):w},n.scale=function(t){return arguments.length?(S=+t,u(),n):S},n.scaleExtent=function(t){return arguments.length?(E=null==t?za:t.map(Number),n):E},n.x=function(t){return arguments.length?(M=t,y=t.copy(),w=[0,0],S=1,n):M},n.y=function(t){return arguments.length?(b=t,x=t.copy(),w=[0,0],S=1,n):b},oa.rebind(n,k,"on")};var Ca,za=[0,1/0],Da="onwheel"in ca?(Ca=function(){return-oa.event.deltaY*(oa.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ca?(Ca=function(){return oa.event.wheelDelta},"mousewheel"):(Ca=function(){return-oa.event.detail},"MozMousePixelScroll");F.prototype.toString=function(){return this.rgb()+""},oa.hsl=function(n,t,e){return arguments.length===1?n instanceof P?H(n.h,n.s,n.l):ut(""+n,at,H):H(+n,+t,+e)};var ja=P.prototype=new F;ja.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),H(this.h,this.s,this.l/n)},ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),H(this.h,this.s,n*this.l)},ja.rgb=function(){return R(this.h,this.s,this.l)};var La=Math.PI,Fa=1e-6,Ha=La/180,Pa=180/La;oa.hcl=function(n,t,e){return arguments.length===1?n instanceof B?Z(n.h,n.c,n.l):n instanceof G?W(n.l,n.a,n.b):W((n=ot((n=oa.rgb(n)).r,n.g,n.b)).l,n.a,n.b):Z(+n,+t,+e)};var Ra=B.prototype=new F;Ra.brighter=function(n){return Z(this.h,this.c,Math.min(100,this.l+Oa*(arguments.length?n:1)))},Ra.darker=function(n){return Z(this.h,this.c,Math.max(0,this.l-Oa*(arguments.length?n:1)))},Ra.rgb=function(){return $(this.h,this.c,this.l).rgb()},oa.lab=function(n,t,e){return arguments.length===1?n instanceof G?J(n.l,n.a,n.b):n instanceof B?$(n.l,n.c,n.h):ot((n=oa.rgb(n)).r,n.g,n.b):J(+n,+t,+e)};var Oa=18,Ya=.95047,Ua=1,Ia=1.08883,Va=G.prototype=new F;Va.brighter=function(n){return J(Math.min(100,this.l+Oa*(arguments.length?n:1)),this.a,this.b)},Va.darker=function(n){return J(Math.max(0,this.l-Oa*(arguments.length?n:1)),this.a,this.b)},Va.rgb=function(){return K(this.l,this.a,this.b)},oa.rgb=function(n,t,e){return arguments.length===1?n instanceof rt?et(n.r,n.g,n.b):ut(""+n,et,R):et(~~n,~~t,~~e)};var Xa=rt.prototype=new F;Xa.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),et(Math.min(255,Math.floor(t/n)),Math.min(255,Math.floor(e/n)),Math.min(255,Math.floor(r/n)))):et(i,i,i)},Xa.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),et(Math.floor(n*this.r),Math.floor(n*this.g),Math.floor(n*this.b))},Xa.hsl=function(){return at(this.r,this.g,this.b)},Xa.toString=function(){return"#"+it(this.r)+it(this.g)+it(this.b)};var Za=oa.map({aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"});Za.forEach(function(n,t){Za.set(n,ut(t,et,R))}),oa.functor=ft,oa.xhr=function(n,t,e){function r(){var n=c.status;!n&&c.responseText||n>=200&&300>n||304===n?u.load.call(i,o.call(i,c)):u.error.call(i,c)}var i={},u=oa.dispatch("progress","load","error"),a={},o=st,c=new(la.XDomainRequest&&/^(http(s)?:)?\/\//.test(n)?XDomainRequest:XMLHttpRequest);return"onload"in c?c.onload=c.onerror=r:c.onreadystatechange=function(){c.readyState>3&&r()},c.onprogress=function(n){var t=oa.event;oa.event=n;try{u.progress.call(i,c)}finally{oa.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.response=function(n){return o=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(va(arguments)))}}),i.send=function(e,r,u){if(arguments.length===2&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var o in a)c.setRequestHeader(o,a[o]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},oa.rebind(i,u,"on"),arguments.length===2&&"function"==typeof t&&(e=t,t=null),null==e?i:i.get(ht(e))},oa.csv=gt(",","text/csv"),oa.tsv=gt(" ","text/tab-separated-values");var Ba,$a,Ja=0,Ga={},Ka=null;oa.timer=function(n,t,e){if(arguments.length<3){if(arguments.length<2)t=0;else if(!isFinite(t))return;e=Date.now()}var r=Ga[n.id];r&&r.callback===n?(r.then=e,r.delay=t):Ga[n.id=++Ja]=Ka={callback:n,then:e,delay:t,next:Ka},Ba||($a=clearTimeout($a),Ba=1,Wa(pt))},oa.timer.flush=function(){for(var n,t=Date.now(),e=Ka;e;)n=t-e.then,e.delay||(e.flush=e.callback(n)),e=e.next;dt()};var Wa=la.requestAnimationFrame||la.webkitRequestAnimationFrame||la.mozRequestAnimationFrame||la.oRequestAnimationFrame||la.msRequestAnimationFrame||function(n){setTimeout(n,17)},Qa=".",no=",",to=[3,3],eo=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"].map(mt);oa.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=oa.round(n,vt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,Math.floor((0>=e?e+1:e-1)/3)*3))),eo[8+e/3]},oa.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)},oa.format=function(n){var t=ro.exec(n),e=t[1]||" ",r=t[2]||">",i=t[3]||"",u=t[4]||"",a=t[5],o=+t[6],c=t[7],l=t[8],f=t[9],s=1,h="",g=!1;switch(l&&(l=+l.substring(1)),(a||"0"===e&&"="===r)&&(a=e="0",r="=",c&&(o-=Math.floor((o-1)/4))),f){case"n":c=!0,f="g";break;case"%":s=100,h="%",f="f";break;case"p":s=100,h="%",f="r";break;case"b":case"o":case"x":case"X":u&&(u="0"+f.toLowerCase());case"c":case"d":g=!0,l=0;break;case"s":s=-1,f="r"}"#"===u&&(u=""),"r"!=f||l||(f="g"),null!=l&&("g"==f?l=Math.max(1,Math.min(21,l)):("e"==f||"f"==f)&&(l=Math.max(0,Math.min(20,l)))),f=io.get(f)||yt;var p=a&&c;return function(n){if(g&&n%1)return"";var t=0>n||0===n&&0>1/n?(n=-n,"-"):i;if(0>s){var d=oa.formatPrefix(n,l);n=d.scale(n),h=d.symbol}else n*=s;n=f(n,l),!a&&c&&(n=uo(n));var m=u.length+n.length+(p?0:t.length),v=o>m?Array(m=o-m+1).join(e):"";return p&&(n=uo(v+n)),Qa&&n.replace(".",Qa),t+=u,("<"===r?t+n+v:">"===r?v+t+n:"^"===r?v.substring(0,m>>=1)+t+n+v.substring(m):t+(p?n:v+n))+h}};var ro=/(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,io=oa.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=oa.round(n,vt(n,t))).toFixed(Math.max(0,Math.min(20,vt(n*(1+1e-15),t))))}}),uo=st;if(to){var ao=to.length;uo=function(n){for(var t=n.lastIndexOf("."),e=t>=0?"."+n.substring(t+1):(t=n.length,""),r=[],i=0,u=to[0];t>0&&u>0;)r.push(n.substring(t-=u,t+u)),u=to[i=(i+1)%ao];return r.reverse().join(no||"")+e}}oa.geo={},oa.geo.stream=function(n,t){n&&oo.hasOwnProperty(n.type)?oo[n.type](n,t):Mt(n,t)};var oo={Feature:function(n,t){Mt(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++r<i;)Mt(e[r].geometry,t)}},co={Sphere:function(n,t){t.sphere()},Point:function(n,t){var e=n.coordinates;t.point(e[0],e[1])},MultiPoint:function(n,t){for(var e,r=n.coordinates,i=-1,u=r.length;++i<u;)e=r[i],t.point(e[0],e[1])},LineString:function(n,t){xt(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)xt(e[r],t,0)},Polygon:function(n,t){bt(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)bt(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,i=e.length;++r<i;)Mt(e[r],t)}};oa.geo.area=function(n){return lo=0,oa.geo.stream(n,ho),lo};var lo,fo,so,ho={sphere:function(){lo+=4*La},point:T,lineStart:T,lineEnd:T,polygonStart:function(){fo=1,so=0,ho.lineStart=_t},polygonEnd:function(){var n=2*Math.atan2(so,fo);lo+=0>n?4*La+n:n,ho.lineStart=ho.lineEnd=ho.point=T}};oa.geo.bounds=wt(st),oa.geo.centroid=function(n){go=po=mo=vo=yo=0,oa.geo.stream(n,Mo);var t;return po&&Math.abs(t=Math.sqrt(mo*mo+vo*vo+yo*yo))>Fa?[Math.atan2(vo,mo)*Pa,Math.asin(Math.max(-1,Math.min(1,yo/t)))*Pa]:void 0};var go,po,mo,vo,yo,Mo={sphere:function(){2>go&&(go=2,po=mo=vo=yo=0)},point:St,lineStart:kt,lineEnd:At,polygonStart:function(){2>go&&(go=2,po=mo=vo=yo=0),Mo.lineStart=Et},polygonEnd:function(){Mo.lineStart=kt}},xo=Rt(jt,Vt,Zt),bo=1e9;oa.geo.projection=Wt,oa.geo.projectionMutator=Qt,(oa.geo.equirectangular=function(){return Wt(te)}).raw=te.invert=te,oa.geo.rotation=function(n){function t(t){return t=n(t[0]*Ha,t[1]*Ha),t[0]*=Pa,t[1]*=Pa,t}return n=ee(n[0]%360*Ha,n[1]*Ha,n.length>2?n[2]*Ha:0),t.invert=function(t){return t=n.invert(t[0]*Ha,t[1]*Ha),t[0]*=Pa,t[1]*=Pa,t},t},oa.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ee(-n[0]*Ha,-n[1]*Ha,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ae((t=+r)*Ha,i*Ha),n):t},n.precision=function(r){return arguments.length?(e=ae(t*Ha,(i=+r)*Ha),n):i},n.angle(90)},oa.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Ha,i=n[1]*Ha,u=t[1]*Ha,a=Math.sin(r),o=Math.cos(r),c=Math.sin(i),l=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*a)*e+(e=l*f-c*s*o)*e),c*f+l*s*o)},oa.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return oa.range(Math.ceil(u/m)*m,i,m).map(h).concat(oa.range(Math.ceil(l/v)*v,c,v).map(g)).concat(oa.range(Math.ceil(r/p)*p,e,p).filter(function(n){return Math.abs(n%m)>Fa}).map(f)).concat(oa.range(Math.ceil(o/d)*d,a,d).filter(function(n){return Math.abs(n%v)>Fa}).map(s))}var e,r,i,u,a,o,c,l,f,s,h,g,p=10,d=p,m=90,v=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(g(c).slice(1),h(i).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],l=+t[0][1],c=+t[1][1],u>i&&(t=u,u=i,i=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[u,l],[i,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],o=+t[0][1],a=+t[1][1],r>e&&(t=r,r=e,e=t),o>a&&(t=o,o=a,a=t),n.precision(y)):[[r,o],[e,a]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(m=+t[0],v=+t[1],n):[m,v]},n.minorStep=function(t){return arguments.length?(p=+t[0],d=+t[1],n):[p,d]},n.precision=function(t){return arguments.length?(y=+t,f=ce(o,a,90),s=le(r,e,y),h=ce(l,c,90),g=le(u,i,y),n):y},n.majorExtent([[-180,-90+Fa],[180,90-Fa]]).minorExtent([[-180,-80-Fa],[180,80+Fa]])},oa.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=fe,i=se;return n.distance=function(){return oa.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},oa.geo.interpolate=function(n,t){return he(n[0]*Ha,n[1]*Ha,t[0]*Ha,t[1]*Ha)},oa.geo.length=function(n){return _o=0,oa.geo.stream(n,wo),_o};var _o,wo={sphere:T,point:T,lineStart:ge,lineEnd:T,polygonStart:T,polygonEnd:T};(oa.geo.conicEqualArea=function(){return pe(de)}).raw=de,oa.geo.albersUsa=function(){function n(n){return t(n)(n)}function t(n){var t=n[0],e=n[1];return e>50?a:-140>t?o:21>e?c:u}var e,r,i,u=oa.geo.conicEqualArea().rotate([98,0]).center([0,38]).parallels([29.5,45.5]),a=oa.geo.conicEqualArea().rotate([160,0]).center([0,60]).parallels([55,65]),o=oa.geo.conicEqualArea().rotate([160,0]).center([0,20]).parallels([8,18]),c=oa.geo.conicEqualArea().rotate([60,0]).center([0,10]).parallels([8,18]);return n.invert=function(n){return e(n)||r(n)||i(n)||u.invert(n)},n.scale=function(t){return arguments.length?(u.scale(t),a.scale(.6*t),o.scale(t),c.scale(1.5*t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var l=u.scale(),f=t[0],s=t[1];return u.translate(t),a.translate([f-.4*l,s+.17*l]),o.translate([f-.19*l,s+.2*l]),c.translate([f+.58*l,s+.43*l]),e=me(a,[[-180,50],[-130,72]]),r=me(o,[[-164,18],[-154,24]]),i=me(c,[[-67.5,17.5],[-65,19]]),n},n.scale(1e3)};var So,Eo,ko={point:T,lineStart:T,lineEnd:T,polygonStart:function(){Eo=0,ko.lineStart=ve},polygonEnd:function(){ko.lineStart=ko.lineEnd=ko.point=T,So+=Math.abs(Eo/2)}},Ao={point:Me,lineStart:xe,lineEnd:be,polygonStart:function(){Ao.lineStart=_e},polygonEnd:function(){Ao.point=Me,Ao.lineStart=xe,Ao.lineEnd=be}};oa.geo.path=function(){function n(n){return n&&oa.geo.stream(n,r(i.pointRadius("function"==typeof u?+u.apply(this,arguments):u))),i.result()}var t,e,r,i,u=4.5;return n.area=function(n){return So=0,oa.geo.stream(n,r(ko)),So},n.centroid=function(n){return go=mo=vo=yo=0,oa.geo.stream(n,r(Ao)),yo?[mo/yo,vo/yo]:void 0},n.bounds=function(n){return wt(r)(n)},n.projection=function(e){return arguments.length?(r=(t=e)?e.stream||Ee(e):st,n):t},n.context=function(t){return arguments.length?(i=(e=t)==null?new ye:new we(t),n):e},n.pointRadius=function(t){return arguments.length?(u="function"==typeof t?t:+t,n):u},n.projection(oa.geo.albersUsa()).context(null)},oa.geo.albers=function(){return oa.geo.conicEqualArea().parallels([29.5,45.5]).rotate([98,0]).center([0,38]).scale(1e3)};var No=ke(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(oa.geo.azimuthalEqualArea=function(){return Wt(No)}).raw=No;var qo=ke(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},st);(oa.geo.azimuthalEquidistant=function(){return Wt(qo)}).raw=qo,(oa.geo.conicConformal=function(){return pe(Ae)}).raw=Ae,(oa.geo.conicEquidistant=function(){return pe(Ne)}).raw=Ne;var To=ke(function(n){return 1/n},Math.atan);(oa.geo.gnomonic=function(){return Wt(To)}).raw=To,qe.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-La/2]},(oa.geo.mercator=function(){return Te(qe)}).raw=qe;var Co=ke(function(){return 1},Math.asin);(oa.geo.orthographic=function(){return Wt(Co)}).raw=Co;var zo=ke(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(oa.geo.stereographic=function(){return Wt(zo)}).raw=zo,Ce.invert=function(n,t){return[Math.atan2(I(n),Math.cos(t)),U(Math.sin(t)/V(n))]},(oa.geo.transverseMercator=function(){return Te(Ce)}).raw=Ce,oa.geom={},oa.svg={},oa.svg.line=function(){return ze(st)};var Do=oa.map({linear:Le,"linear-closed":Fe,"step-before":He,"step-after":Pe,basis:Ve,"basis-open":Xe,"basis-closed":Ze,bundle:Be,cardinal:Ye,"cardinal-open":Re,"cardinal-closed":Oe,monotone:Qe});Do.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var jo=[0,2/3,1/3,0],Lo=[0,1/3,2/3,0],Fo=[0,1/6,2/3,1/6];oa.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i,u,a,o,c,l,f,s,h,g,p,d=ft(e),m=ft(r),v=n.length,y=v-1,M=[],x=[],b=0;if(d===De&&r===je)t=n;else for(u=0,t=[];v>u;++u)t.push([+d.call(this,i=n[u],u),+m.call(this,i,u)]);for(u=1;v>u;++u)(t[u][1]<t[b][1]||t[u][1]==t[b][1]&&t[u][0]<t[b][0])&&(b=u);for(u=0;v>u;++u)u!==b&&(c=t[u][1]-t[b][1],o=t[u][0]-t[b][0],M.push({angle:Math.atan2(c,o),index:u}));for(M.sort(function(n,t){return n.angle-t.angle}),g=M[0].angle,h=M[0].index,s=0,u=1;y>u;++u){if(a=M[u].index,g==M[u].angle){if(o=t[h][0]-t[b][0],c=t[h][1]-t[b][1],l=t[a][0]-t[b][0],f=t[a][1]-t[b][1],o*o+c*c>=l*l+f*f){M[u].index=-1;continue}M[s].index=-1}g=M[u].angle,s=u,h=a}for(x.push(b),u=0,a=0;2>u;++a)M[a].index>-1&&(x.push(M[a].index),u++);for(p=x.length;y>a;++a)if(!(M[a].index<0)){for(;!nr(x[p-2],x[p-1],M[a].index,t);)--p;x[p++]=M[a].index}var _=[];for(u=p-1;u>=0;--u)_.push(n[x[u]]);return _}var e=De,r=je;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},oa.geom.polygon=function(n){return n.area=function(){for(var t=0,e=n.length,r=n[e-1][1]*n[0][0]-n[e-1][0]*n[0][1];++t<e;)r+=n[t-1][1]*n[t][0]-n[t-1][0]*n[t][1];return.5*r},n.centroid=function(t){var e,r,i=-1,u=n.length,a=0,o=0,c=n[u-1];for(arguments.length||(t=-1/(6*n.area()));++i<u;)e=c,c=n[i],r=e[0]*c[1]-c[0]*e[1],a+=(e[0]+c[0])*r,o+=(e[1]+c[1])*r;return[a*t,o*t]},n.clip=function(t){for(var e,r,i,u,a,o,c=-1,l=n.length,f=n[l-1];++c<l;){for(e=t.slice(),t.length=0,u=n[c],a=e[(i=e.length)-1],r=-1;++r<i;)o=e[r],tr(o,f,u)?(tr(a,f,u)||t.push(er(a,o,f,u)),t.push(o)):tr(a,f,u)&&t.push(er(a,o,f,u)),a=o;f=u}return t},n},oa.geom.delaunay=function(n){var t=n.map(function(){return[]}),e=[];return rr(n,function(e){t[e.region.l.index].push(n[e.region.r.index])}),t.forEach(function(t,r){var i=n[r],u=i[0],a=i[1];t.forEach(function(n){n.angle=Math.atan2(n[0]-u,n[1]-a)}),t.sort(function(n,t){return n.angle-t.angle});for(var o=0,c=t.length-1;c>o;o++)e.push([i,t[o],t[o+1]])}),e},oa.geom.voronoi=function(n){function t(n){var t,r,a,o=n.map(function(){return[]}),c=ft(i),l=ft(u),f=n.length,s=1e6;if(c===De&&l===je)t=n;else for(t=[],a=0;f>a;++a)t.push([+c.call(this,r=n[a],a),+l.call(this,r,a)]);if(rr(t,function(n){var t,e,r,i,u,a;n.a===1&&n.b>=0?(t=n.ep.r,e=n.ep.l):(t=n.ep.l,e=n.ep.r),n.a===1?(u=t?t.y:-s,r=n.c-n.b*u,a=e?e.y:s,i=n.c-n.b*a):(r=t?t.x:-s,u=n.c-n.a*r,i=e?e.x:s,a=n.c-n.a*i);var c=[r,u],l=[i,a];o[n.region.l.index].push(c,l),o[n.region.r.index].push(c,l)}),o=o.map(function(n,e){var r=t[e][0],i=t[e][1],u=n.map(function(n){return Math.atan2(n[0]-r,n[1]-i)}),a=oa.range(n.length).sort(function(n,t){return u[n]-u[t]});return a.filter(function(n,t){return!t||u[n]-u[a[t-1]]>Fa}).map(function(t){return n[t]})}),o.forEach(function(n,e){var r=n.length;if(!r)return n.push([-s,-s],[-s,s],[s,s],[s,-s]);if(!(r>2)){var i=t[e],u=n[0],a=n[1],o=i[0],c=i[1],l=u[0],f=u[1],h=a[0],g=a[1],p=Math.abs(h-l),d=g-f;if(Math.abs(d)<Fa){var m=f>c?-s:s;n.push([-s,m],[s,m])}else if(Fa>p){var v=l>o?-s:s;n.push([v,-s],[v,s])}else{var m=(l-o)*(g-f)>(h-l)*(f-c)?s:-s,y=Math.abs(d)-p;Math.abs(y)<Fa?n.push([0>d?m:-m,m]):(y>0&&(m*=-1),n.push([-s,m],[s,m]))}}}),e)for(a=0;f>a;++a)e(o[a]);for(a=0;f>a;++a)o[a].point=n[a];return o}var e,r=null,i=De,u=je;return arguments.length?t(n):(t.x=function(n){return arguments.length?(i=n,t):i},t.y=function(n){return arguments.length?(u=n,t):u},t.size=function(n){return arguments.length?(null==n?e=null:(r=[+n[0],+n[1]],e=oa.geom.polygon([[0,0],[0,r[1]],r,[r[0],0]]).clip),t):r},t.links=function(n){var t,e,r,a=n.map(function(){return[]}),o=[],c=ft(i),l=ft(u),f=n.length;if(c===De&&l===je)t=n;else for(r=0;f>r;++r)t.push([+c.call(this,e=n[r],r),+l.call(this,e,r)]);return rr(t,function(t){var e=t.region.l.index,r=t.region.r.index;a[e][r]||(a[e][r]=a[r][e]=!0,o.push({source:n[e],target:n[r]}))}),o},t.triangles=function(n){if(i===De&&u===je)return oa.geom.delaunay(n);var t,e,r,a,o,c=ft(i),l=ft(u);for(a=0,t=[],o=n.length;o>a;++a)e=[+c.call(this,r=n[a],a),+l.call(this,r,a)],e.data=r,t.push(e);return oa.geom.delaunay(t).map(function(n){return n.map(function(n){return n.data})})},t)};var Ho={l:"r",r:"l"};oa.geom.quadtree=function(n,t,e,r,i){function u(n){function u(n,t,e,r,i,u,a,o){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,f=n.y;
-if(null!=c)if(Math.abs(c-e)+Math.abs(f-r)<.01)l(n,t,e,r,i,u,a,o);else{var s=n.point;n.x=n.y=n.point=null,l(n,s,c,f,i,u,a,o),l(n,t,e,r,i,u,a,o)}else n.x=e,n.y=r,n.point=t}else l(n,t,e,r,i,u,a,o)}function l(n,t,e,r,i,a,o,c){var l=.5*(i+o),f=.5*(a+c),s=e>=l,h=r>=f,g=(h<<1)+s;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=ar()),s?i=l:o=l,h?a=f:c=f,u(n,t,e,r,i,a,o,c)}var f,s,h,g,p,d,m,v,y,M=ft(o),x=ft(c);if(null!=t)d=t,m=e,v=r,y=i;else if(v=y=-(d=m=1/0),s=[],h=[],p=n.length,a)for(g=0;p>g;++g)f=n[g],f.x<d&&(d=f.x),f.y<m&&(m=f.y),f.x>v&&(v=f.x),f.y>y&&(y=f.y),s.push(f.x),h.push(f.y);else for(g=0;p>g;++g){var b=+M(f=n[g],g),_=+x(f,g);d>b&&(d=b),m>_&&(m=_),b>v&&(v=b),_>y&&(y=_),s.push(b),h.push(_)}var w=v-d,S=y-m;w>S?y=m+w:v=d+S;var E=ar();if(E.add=function(n){u(E,n,+M(n,++g),+x(n,g),d,m,v,y)},E.visit=function(n){or(n,E,d,m,v,y)},g=-1,null==t){for(;++g<p;)u(E,n[g],s[g],h[g],d,m,v,y);--g}else n.forEach(E.add);return s=h=n=f=null,E}var a,o=De,c=je;return(a=arguments.length)?(o=ir,c=ur,3===a&&(i=e,r=t,e=t=0),u(n)):(u.x=function(n){return arguments.length?(o=n,u):o},u.y=function(n){return arguments.length?(c=n,u):c},u.size=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=e=0,r=+n[0],i=+n[1]),u):null==t?null:[r,i]},u)},oa.interpolateRgb=cr,oa.transform=function(n){var t=ca.createElementNS(oa.ns.prefix.svg,"g");return(oa.transform=function(n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate();return new lr(e?e.matrix:Po)})(n)},lr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var Po={a:1,b:0,c:0,d:1,e:0,f:0};oa.interpolateNumber=gr,oa.interpolateTransform=pr,oa.interpolateObject=dr,oa.interpolateString=mr;var Ro=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;oa.interpolate=vr,oa.interpolators=[function(n,t){var e=typeof t;return("string"===e||e!==typeof n?Za.has(t)||/^(#|rgb\(|hsl\()/.test(t)?cr:mr:t instanceof F?cr:"object"===e?Array.isArray(t)?Mr:dr:gr)(n,t)}],oa.interpolateArray=Mr;var Oo=function(){return st},Yo=oa.map({linear:Oo,poly:kr,quad:function(){return wr},cubic:function(){return Sr},sin:function(){return Ar},exp:function(){return Nr},circle:function(){return qr},elastic:Tr,back:Cr,bounce:function(){return zr}}),Uo=oa.map({"in":st,out:br,"in-out":_r,"out-in":function(n){return _r(br(n))}});oa.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=Yo.get(e)||Oo,r=Uo.get(r)||st,xr(r(e.apply(null,Array.prototype.slice.call(arguments,1))))},oa.interpolateHcl=Dr,oa.interpolateHsl=jr,oa.interpolateLab=Lr,oa.interpolateRound=Fr,oa.layout={},oa.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Rr(n[e]));return t}},oa.layout.chord=function(){function n(){var n,l,s,h,g,p={},d=[],m=oa.range(u),v=[];for(e=[],r=[],n=0,h=-1;++h<u;){for(l=0,g=-1;++g<u;)l+=i[h][g];d.push(l),v.push(oa.range(u)),n+=l}for(a&&m.sort(function(n,t){return a(d[n],d[t])}),o&&v.forEach(function(n,t){n.sort(function(n,e){return o(i[t][n],i[t][e])})}),n=(2*La-f*u)/n,l=0,h=-1;++h<u;){for(s=l,g=-1;++g<u;){var y=m[h],M=v[y][g],x=i[y][M],b=l,_=l+=x*n;p[y+"-"+M]={index:y,subindex:M,startAngle:b,endAngle:_,value:x}}r[y]={index:y,startAngle:s,endAngle:l,value:(l-s)/n},l+=f}for(h=-1;++h<u;)for(g=h-1;++g<u;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,i,u,a,o,c,l={},f=0;return l.matrix=function(n){return arguments.length?(u=(i=n)&&i.length,e=r=null,l):i},l.padding=function(n){return arguments.length?(f=n,e=r=null,l):f},l.sortGroups=function(n){return arguments.length?(a=n,e=r=null,l):a},l.sortSubgroups=function(n){return arguments.length?(o=n,e=null,l):o},l.sortChords=function(n){return arguments.length?(c=n,e&&t(),l):c},l.chords=function(){return e||n(),e},l.groups=function(){return r||n(),r},l},oa.layout.force=function(){function n(n){return function(t,e,r,i){if(t.point!==n){var u=t.cx-n.x,a=t.cy-n.y,o=1/Math.sqrt(u*u+a*a);if(d>(i-e)*o){var c=t.charge*o*o;return n.px-=u*c,n.py-=a*c,!0}if(t.point&&isFinite(o)){var c=t.pointCharge*o*o;n.px-=u*c,n.py-=a*c}}return!t.charge}}function t(n){n.px=oa.event.x,n.py=oa.event.y,o.resume()}var e,r,i,u,a,o={},c=oa.dispatch("start","tick","end"),l=[1,1],f=.9,s=Io,h=Vo,g=-30,p=.1,d=.8,m=[],v=[];return o.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,o,s,h,d,y,M,x,b=m.length,_=v.length;for(e=0;_>e;++e)o=v[e],s=o.source,h=o.target,M=h.x-s.x,x=h.y-s.y,(d=M*M+x*x)&&(d=r*u[e]*((d=Math.sqrt(d))-i[e])/d,M*=d,x*=d,h.x-=M*(y=s.weight/(h.weight+s.weight)),h.y-=x*y,s.x+=M*(y=1-y),s.y+=x*y);if((y=r*p)&&(M=l[0]/2,x=l[1]/2,e=-1,y))for(;++e<b;)o=m[e],o.x+=(M-o.x)*y,o.y+=(x-o.y)*y;if(g)for(Zr(t=oa.geom.quadtree(m),r,a),e=-1;++e<b;)(o=m[e]).fixed||t.visit(n(o));for(e=-1;++e<b;)o=m[e],o.fixed?(o.x=o.px,o.y=o.py):(o.x-=(o.px-(o.px=o.x))*f,o.y-=(o.py-(o.py=o.y))*f);c.tick({type:"tick",alpha:r})},o.nodes=function(n){return arguments.length?(m=n,o):m},o.links=function(n){return arguments.length?(v=n,o):v},o.size=function(n){return arguments.length?(l=n,o):l},o.linkDistance=function(n){return arguments.length?(s="function"==typeof n?n:+n,o):s},o.distance=o.linkDistance,o.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,o):h},o.friction=function(n){return arguments.length?(f=+n,o):f},o.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,o):g},o.gravity=function(n){return arguments.length?(p=+n,o):p},o.theta=function(n){return arguments.length?(d=+n,o):d},o.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),oa.timer(o.tick)),o):r},o.start=function(){function n(n,r){for(var i,u=t(e),a=-1,o=u.length;++a<o;)if(!isNaN(i=u[a][n]))return i;return Math.random()*r}function t(){if(!c){for(c=[],r=0;p>r;++r)c[r]=[];for(r=0;d>r;++r){var n=v[r];c[n.source.index].push(n.target),c[n.target.index].push(n.source)}}return c[e]}var e,r,c,f,p=m.length,d=v.length,y=l[0],M=l[1];for(e=0;p>e;++e)(f=m[e]).index=e,f.weight=0;for(e=0;d>e;++e)f=v[e],typeof f.source=="number"&&(f.source=m[f.source]),typeof f.target=="number"&&(f.target=m[f.target]),++f.source.weight,++f.target.weight;for(e=0;p>e;++e)f=m[e],isNaN(f.x)&&(f.x=n("x",y)),isNaN(f.y)&&(f.y=n("y",M)),isNaN(f.px)&&(f.px=f.x),isNaN(f.py)&&(f.py=f.y);if(i=[],"function"==typeof s)for(e=0;d>e;++e)i[e]=+s.call(this,v[e],e);else for(e=0;d>e;++e)i[e]=s;if(u=[],"function"==typeof h)for(e=0;d>e;++e)u[e]=+h.call(this,v[e],e);else for(e=0;d>e;++e)u[e]=h;if(a=[],"function"==typeof g)for(e=0;p>e;++e)a[e]=+g.call(this,m[e],e);else for(e=0;p>e;++e)a[e]=g;return o.resume()},o.resume=function(){return o.alpha(.1)},o.stop=function(){return o.alpha(0)},o.drag=function(){return e||(e=oa.behavior.drag().origin(st).on("dragstart.force",Ur).on("drag.force",t).on("dragend.force",Ir)),arguments.length?(this.on("mouseover.force",Vr).on("mouseout.force",Xr).call(e),void 0):e},oa.rebind(o,c,"on")};var Io=20,Vo=1;oa.layout.hierarchy=function(){function n(t,a,o){var c=i.call(e,t,a);if(t.depth=a,o.push(t),c&&(l=c.length)){for(var l,f,s=-1,h=t.children=[],g=0,p=a+1;++s<l;)f=n(c[s],p,o),f.parent=t,h.push(f),g+=f.value;r&&h.sort(r),u&&(t.value=g)}else u&&(t.value=+u.call(e,t,a)||0);return t}function t(n,r){var i=n.children,a=0;if(i&&(o=i.length))for(var o,c=-1,l=r+1;++c<o;)a+=t(i[c],l);else u&&(a=+u.call(e,n,r)||0);return u&&(n.value=a),a}function e(t){var e=[];return n(t,0,e),e}var r=Gr,i=$r,u=Jr;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(i=n,e):i},e.value=function(n){return arguments.length?(u=n,e):u},e.revalue=function(n){return t(n,0),n},e},oa.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(a=u.length)){var a,o,c,l=-1;for(r=t.value?r/t.value:0;++l<a;)n(o=u[l],e,c=o.value*r,i),e+=c}}function t(n){var e=n.children,r=0;if(e&&(i=e.length))for(var i,u=-1;++u<i;)r=Math.max(r,t(e[u]));return 1+r}function e(e,u){var a=r.call(this,e,u);return n(a[0],0,i[0],i[1]/t(a[0])),a}var r=oa.layout.hierarchy(),i=[1,1];return e.size=function(n){return arguments.length?(i=n,e):i},Br(e,r)},oa.layout.pie=function(){function n(u){var a=u.map(function(e,r){return+t.call(n,e,r)}),o=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof i?i.apply(this,arguments):i)-o)/oa.sum(a),l=oa.range(u.length);null!=e&&l.sort(e===Xo?function(n,t){return a[t]-a[n]}:function(n,t){return e(u[n],u[t])});var f=[];return l.forEach(function(n){var t;f[n]={data:u[n],value:t=a[n],startAngle:o,endAngle:o+=t*c}}),f}var t=Number,e=Xo,r=0,i=2*La;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n};var Xo={};oa.layout.stack=function(){function n(o,c){var l=o.map(function(e,r){return t.call(n,e,r)}),f=l.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),a.call(n,t,e)]})}),s=e.call(n,f,c);l=oa.permute(l,s),f=oa.permute(f,s);var h,g,p,d=r.call(n,f,c),m=l.length,v=l[0].length;for(g=0;v>g;++g)for(i.call(n,l[0][g],p=d[g],f[0][g][1]),h=1;m>h;++h)i.call(n,l[h][g],p+=f[h-1][g][1],f[h][g][1]);return o}var t=st,e=ti,r=ei,i=ni,u=Wr,a=Qr;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:Zo.get(t)||ti,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:Bo.get(t)||ei,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(a=t,n):a},n.out=function(t){return arguments.length?(i=t,n):i},n};var Zo=oa.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(ri),u=n.map(ii),a=oa.range(r).sort(function(n,t){return i[n]-i[t]}),o=0,c=0,l=[],f=[];for(t=0;r>t;++t)e=a[t],c>o?(o+=u[e],l.push(e)):(c+=u[e],f.push(e));return f.reverse().concat(l)},reverse:function(n){return oa.range(n.length).reverse()},"default":ti}),Bo=oa.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,a=[],o=0,c=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>o&&(o=r),a.push(r)}for(e=0;u>e;++e)c[e]=(o-a[e])/2;return c},wiggle:function(n){var t,e,r,i,u,a,o,c,l,f=n.length,s=n[0],h=s.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,o=s[e][0]-s[e-1][0];f>t;++t){for(r=0,a=(n[t][e][1]-n[t][e-1][1])/(2*o);t>r;++r)a+=(n[r][e][1]-n[r][e-1][1])/o;u+=a*n[t][e][1]}g[e]=c-=i?u/i*o:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,i=n.length,u=n[0].length,a=1/i,o=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=a}for(e=0;u>e;++e)o[e]=0;return o},zero:ei});oa.layout.histogram=function(){function n(n,u){for(var a,o,c=[],l=n.map(e,this),f=r.call(this,l,u),s=i.call(this,f,l,u),u=-1,h=l.length,g=s.length-1,p=t?1:1/h;++u<g;)a=c[u]=[],a.dx=s[u+1]-(a.x=s[u]),a.y=0;if(g>0)for(u=-1;++u<h;)o=l[u],o>=f[0]&&o<=f[1]&&(a=c[oa.bisect(s,o,1,g)-1],a.y+=p,a.push(n[u]));return c}var t=!0,e=Number,r=ci,i=ai;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=ft(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return oi(n,t)}:ft(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},oa.layout.tree=function(){function n(n,i){function u(n,t){var r=n.children,i=n._tree;if(r&&(a=r.length)){for(var a,c,l,f=r[0],s=f,h=-1;++h<a;)l=r[h],u(l,c),s=o(l,c,s),c=l;vi(n);var g=.5*(f._tree.prelim+l._tree.prelim);t?(i.prelim=t._tree.prelim+e(n,t),i.mod=i.prelim-g):i.prelim=g}else t&&(i.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,i=-1;for(t+=n._tree.mod;++i<r;)a(e[i],t)}}function o(n,t,r){if(t){for(var i,u=n,a=n,o=t,c=n.parent.children[0],l=u._tree.mod,f=a._tree.mod,s=o._tree.mod,h=c._tree.mod;o=si(o),u=fi(u),o&&u;)c=fi(c),a=si(a),a._tree.ancestor=n,i=o._tree.prelim+s-u._tree.prelim-l+e(o,u),i>0&&(yi(Mi(o,n,r),n,i),l+=i,f+=i),s+=o._tree.mod,l+=u._tree.mod,h+=c._tree.mod,f+=a._tree.mod;o&&!si(a)&&(a._tree.thread=o,a._tree.mod+=s-f),u&&!fi(c)&&(c._tree.thread=u,c._tree.mod+=l-h,r=n)}return r}var c=t.call(this,n,i),l=c[0];mi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),u(l),a(l,-l._tree.prelim);var f=hi(l,pi),s=hi(l,gi),h=hi(l,di),g=f.x-e(f,s)/2,p=s.x+e(s,f)/2,d=h.depth||1;return mi(l,function(n){n.x=(n.x-g)/(p-g)*r[0],n.y=n.depth/d*r[1],delete n._tree}),c}var t=oa.layout.hierarchy().sort(null).value(null),e=li,r=[1,1];return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(r=t,n):r},Br(n,t)},oa.layout.pack=function(){function n(n,i){var u=t.call(this,n,i),a=u[0];a.x=0,a.y=0,mi(a,function(n){n.r=Math.sqrt(n.value)}),mi(a,Si);var o=r[0],c=r[1],l=Math.max(2*a.r/o,2*a.r/c);if(e>0){var f=e*l/2;mi(a,function(n){n.r+=f}),mi(a,Si),mi(a,function(n){n.r-=f}),l=Math.max(2*a.r/o,2*a.r/c)}return Ai(a,o/2,c/2,1/l),u}var t=oa.layout.hierarchy().sort(xi),e=0,r=[1,1];return n.size=function(t){return arguments.length?(r=t,n):r},n.padding=function(t){return arguments.length?(e=+t,n):e},Br(n,t)},oa.layout.cluster=function(){function n(n,i){var u,a=t.call(this,n,i),o=a[0],c=0;mi(o,function(n){var t=n.children;t&&t.length?(n.x=Ti(t),n.y=qi(t)):(n.x=u?c+=e(n,u):0,n.y=0,u=n)});var l=Ci(o),f=zi(o),s=l.x-e(l,f)/2,h=f.x+e(f,l)/2;return mi(o,function(n){n.x=(n.x-s)/(h-s)*r[0],n.y=(1-(o.y?n.y/o.y:1))*r[1]}),a}var t=oa.layout.hierarchy().sort(null).value(null),e=li,r=[1,1];return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(r=t,n):r},Br(n,t)},oa.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++i<u;)r=(e=n[i]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var a,o,c,l=s(e),f=[],h=u.slice(),p=1/0,d="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?e.depth&1?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),f.area=0;(c=h.length)>0;)f.push(a=h[c-1]),f.area+=a.area,"squarify"!==g||(o=r(f,d))<=p?(h.pop(),p=o):(f.area-=f.pop().area,i(f,d,l,!1),d=Math.min(l.dx,l.dy),f.length=f.area=0,p=1/0);f.length&&(i(f,d,l,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,a=s(t),o=r.slice(),c=[];for(n(o,a.dx*a.dy/t.value),c.area=0;u=o.pop();)c.push(u),c.area+=u.area,u.z!=null&&(i(c,u.z?a.dx:a.dy,a,!o.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,a=-1,o=n.length;++a<o;)(e=n[a].area)&&(u>e&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*p/r,r/(t*u*p)):1/0}function i(n,t,e,r){var i,u=-1,a=n.length,o=e.x,l=e.y,f=t?c(n.area/t):0;if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++u<a;)i=n[u],i.x=o,i.y=l,i.dy=f,o+=i.dx=Math.min(e.x+e.dx-o,f?c(i.area/f):0);i.z=!0,i.dx+=e.x+e.dx-o,e.y+=f,e.dy-=f}else{for((r||f>e.dx)&&(f=e.dx);++u<a;)i=n[u],i.x=o,i.y=l,i.dx=f,l+=i.dy=Math.min(e.y+e.dy-l,f?c(i.area/f):0);i.z=!1,i.dy+=e.y+e.dy-l,e.x+=f,e.dx-=f}}function u(r){var i=a||o(r),u=i[0];return u.x=0,u.y=0,u.dx=l[0],u.dy=l[1],a&&o.revalue(u),n([u],u.dx*u.dy/u.value),(a?e:t)(u),h&&(a=i),i}var a,o=oa.layout.hierarchy(),c=Math.round,l=[1,1],f=null,s=Di,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return u.size=function(n){return arguments.length?(l=n,u):l},u.padding=function(n){function t(t){var e=n.call(u,t,t.depth);return null==e?Di(t):ji(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return ji(t,n)}if(!arguments.length)return f;var r;return s=(f=n)==null?Di:(r=typeof n)=="function"?t:"number"===r?(n=[n,n,n,n],e):e,u},u.round=function(n){return arguments.length?(c=n?Math.round:Number,u):c!=Number},u.sticky=function(n){return arguments.length?(h=n,a=null,u):h},u.ratio=function(n){return arguments.length?(p=n,u):p},u.mode=function(n){return arguments.length?(g=n+"",u):g},Br(u,o)},oa.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=Math.random()*2-1,r=Math.random()*2-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=oa.random.normal.apply(oa,arguments);return function(){return Math.exp(n())}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t/n}}},oa.scale={},oa.scale.linear=function(){return Oi([0,1],[0,1],vr,!1)},oa.scale.log=function(){return Zi(oa.scale.linear().domain([0,Math.LN10]),10,Bi,$i)};var $o=oa.format(".0e");oa.scale.pow=function(){return Wi(oa.scale.linear(),1)},oa.scale.sqrt=function(){return oa.scale.pow().exponent(.5)},oa.scale.ordinal=function(){return nu([],{t:"range",a:[[]]})},oa.scale.category10=function(){return oa.scale.ordinal().range(Jo)},oa.scale.category20=function(){return oa.scale.ordinal().range(Go)},oa.scale.category20b=function(){return oa.scale.ordinal().range(Ko)},oa.scale.category20c=function(){return oa.scale.ordinal().range(Wo)};var Jo=["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"],Go=["#1f77b4","#aec7e8","#ff7f0e","#ffbb78","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#8c564b","#c49c94","#e377c2","#f7b6d2","#7f7f7f","#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"],Ko=["#393b79","#5254a3","#6b6ecf","#9c9ede","#637939","#8ca252","#b5cf6b","#cedb9c","#8c6d31","#bd9e39","#e7ba52","#e7cb94","#843c39","#ad494a","#d6616b","#e7969c","#7b4173","#a55194","#ce6dbd","#de9ed6"],Wo=["#3182bd","#6baed6","#9ecae1","#c6dbef","#e6550d","#fd8d3c","#fdae6b","#fdd0a2","#31a354","#74c476","#a1d99b","#c7e9c0","#756bb1","#9e9ac8","#bcbddc","#dadaeb","#636363","#969696","#bdbdbd","#d9d9d9"];oa.scale.quantile=function(){return tu([],[])},oa.scale.quantize=function(){return eu(0,1,[0,1])},oa.scale.threshold=function(){return ru([.5],[0,1])},oa.scale.identity=function(){return iu([0,1])},oa.svg.arc=function(){function n(){var n=t.apply(this,arguments),u=e.apply(this,arguments),a=r.apply(this,arguments)+Qo,o=i.apply(this,arguments)+Qo,c=(a>o&&(c=a,a=o,o=c),o-a),l=La>c?"0":"1",f=Math.cos(a),s=Math.sin(a),h=Math.cos(o),g=Math.sin(o);return c>=nc?n?"M0,"+u+"A"+u+","+u+" 0 1,1 0,"+-u+"A"+u+","+u+" 0 1,1 0,"+u+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+u+"A"+u+","+u+" 0 1,1 0,"+-u+"A"+u+","+u+" 0 1,1 0,"+u+"Z":n?"M"+u*f+","+u*s+"A"+u+","+u+" 0 "+l+",1 "+u*h+","+u*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+l+",0 "+n*f+","+n*s+"Z":"M"+u*f+","+u*s+"A"+u+","+u+" 0 "+l+",1 "+u*h+","+u*g+"L0,0"+"Z"}var t=uu,e=au,r=ou,i=cu;return n.innerRadius=function(e){return arguments.length?(t=ft(e),n):t},n.outerRadius=function(t){return arguments.length?(e=ft(t),n):e},n.startAngle=function(t){return arguments.length?(r=ft(t),n):r},n.endAngle=function(t){return arguments.length?(i=ft(t),n):i},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,u=(r.apply(this,arguments)+i.apply(this,arguments))/2+Qo;return[Math.cos(u)*n,Math.sin(u)*n]},n};var Qo=-La/2,nc=2*La-1e-6;oa.svg.line.radial=function(){var n=ze(lu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},He.reverse=Pe,Pe.reverse=He,oa.svg.area=function(){return fu(st)},oa.svg.area.radial=function(){var n=fu(lu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},oa.svg.chord=function(){function n(n,o){var c=t(this,u,n,o),l=t(this,a,n,o);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?i(c.r,c.p1,c.r,c.p0):i(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+i(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=o.call(n,i,r),a=c.call(n,i,r)+Qo,f=l.call(n,i,r)+Qo;return{r:u,a0:a,a1:f,p0:[u*Math.cos(a),u*Math.sin(a)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>La)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=fe,a=se,o=su,c=ou,l=cu;return n.radius=function(t){return arguments.length?(o=ft(t),n):o},n.source=function(t){return arguments.length?(u=ft(t),n):u},n.target=function(t){return arguments.length?(a=ft(t),n):a},n.startAngle=function(t){return arguments.length?(c=ft(t),n):c},n.endAngle=function(t){return arguments.length?(l=ft(t),n):l},n},oa.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),a=e.call(this,n,i),o=(u.y+a.y)/2,c=[u,{x:u.x,y:o},{x:a.x,y:o},a];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=fe,e=se,r=hu;return n.source=function(e){return arguments.length?(t=ft(e),n):t},n.target=function(t){return arguments.length?(e=ft(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},oa.svg.diagonal.radial=function(){var n=oa.svg.diagonal(),t=hu,e=n.projection;return n.projection=function(n){return arguments.length?e(gu(t=n)):t},n},oa.svg.symbol=function(){function n(n,r){return(tc.get(t.call(this,n,r))||mu)(e.call(this,n,r))}var t=du,e=pu;return n.type=function(e){return arguments.length?(t=ft(e),n):t},n.size=function(t){return arguments.length?(e=ft(t),n):e},n};var tc=oa.map({circle:mu,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*ic)),e=t*ic;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/rc),e=t*rc/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/rc),e=t*rc/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});oa.svg.symbolTypes=tc.keys();var ec,rc=Math.sqrt(3),ic=Math.tan(30*Ha),uc=[],ac=0,oc={ease:Er,delay:0,duration:250};uc.call=Ea.call,uc.empty=Ea.empty,uc.node=Ea.node,oa.transition=function(n){return arguments.length?ec?n.transition():n:Ta.transition()},oa.transition.prototype=uc,uc.select=function(n){var t,e,r,i=this.id,u=[];"function"!=typeof n&&(n=v(n));for(var a=-1,o=this.length;++a<o;){u.push(t=[]);for(var c=this[a],l=-1,f=c.length;++l<f;)(r=c[l])&&(e=n.call(r,r.__data__,l))?("__data__"in r&&(e.__data__=r.__data__),xu(e,l,i,r.__transition__[i]),t.push(e)):t.push(null)}return vu(u,i)},uc.selectAll=function(n){var t,e,r,i,u,a=this.id,o=[];"function"!=typeof n&&(n=y(n));for(var c=-1,l=this.length;++c<l;)for(var f=this[c],s=-1,h=f.length;++s<h;)if(r=f[s]){u=r.__transition__[a],e=n.call(r,r.__data__,s),o.push(t=[]);for(var g=-1,p=e.length;++g<p;)xu(i=e[g],g,a,u),t.push(i)}return vu(o,a)},uc.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=N(n));for(var u=0,a=this.length;a>u;u++){i.push(t=[]);for(var e=this[u],o=0,c=e.length;c>o;o++)(r=e[o])&&n.call(r,r.__data__,o)&&t.push(r)}return vu(i,this.id,this.time).ease(this.ease())},uc.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):j(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},uc.attr=function(n,t){function e(){this.removeAttribute(o)}function r(){this.removeAttributeNS(o.space,o.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(o);return e!==n&&(t=a(e,n),function(n){this.setAttribute(o,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(o.space,o.local);return e!==n&&(t=a(e,n),function(n){this.setAttributeNS(o.space,o.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var a=yr(n),o=oa.ns.qualify(n);return yu(this,"attr."+n,t,o.local?u:i)},uc.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=oa.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},uc.style=function(n,t,e){function r(){this.style.removeProperty(n)}function i(t){return null==t?r:(t+="",function(){var r,i=la.getComputedStyle(this,null).getPropertyValue(n);return i!==t&&(r=a(i,t),function(t){this.style.setProperty(n,r(t),e)})})}var u=arguments.length;if(3>u){if("string"!=typeof n){2>u&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}var a=yr(n);return yu(this,"style."+n,t,i)},uc.styleTween=function(n,t,e){function r(r,i){var u=t.call(this,r,i,la.getComputedStyle(this,null).getPropertyValue(n));return u&&function(t){this.style.setProperty(n,u(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},uc.text=function(n){return yu(this,"text",n,Mu)},uc.remove=function(){return this.each("end.transition",function(){var n;!this.__transition__&&(n=this.parentNode)&&n.removeChild(this)})},uc.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=oa.ease.apply(oa,arguments)),j(this,function(e){e.__transition__[t].ease=n}))},uc.delay=function(n){var t=this.id;return j(this,"function"==typeof n?function(e,r,i){e.__transition__[t].delay=n.call(e,e.__data__,r,i)|0}:(n|=0,function(e){e.__transition__[t].delay=n}))},uc.duration=function(n){var t=this.id;return j(this,"function"==typeof n?function(e,r,i){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,i)|0)}:(n=Math.max(1,0|n),function(e){e.__transition__[t].duration=n}))},uc.each=function(n,t){var e=this.id;if(arguments.length<2){var r=oc,i=ec;ec=e,j(this,function(t,r,i){oc=t.__transition__[e],n.call(t,t.__data__,r,i)}),oc=r,ec=i}else j(this,function(r){r.__transition__[e].event.on(n,t)});return this},uc.transition=function(){for(var n,t,e,r,i=this.id,u=++ac,a=[],o=0,c=this.length;c>o;o++){a.push(n=[]);for(var t=this[o],l=0,f=t.length;f>l;l++)(e=t[l])&&(r=Object.create(e.__transition__[i]),r.delay+=r.duration,xu(e,l,u,r)),n.push(e)}return vu(a,u)},oa.svg.axis=function(){function n(n){n.each(function(){var n,s=oa.select(this),h=null==l?e.ticks?e.ticks.apply(e,c):e.domain():l,g=null==t?e.tickFormat?e.tickFormat.apply(e,c):String:t,p=wu(e,h,f),d=s.selectAll(".tick.minor").data(p,String),m=d.enter().insert("line",".tick").attr("class","tick minor").style("opacity",1e-6),v=oa.transition(d.exit()).style("opacity",1e-6).remove(),y=oa.transition(d).style("opacity",1),M=s.selectAll(".tick.major").data(h,String),x=M.enter().insert("g","path").attr("class","tick major").style("opacity",1e-6),b=oa.transition(M.exit()).style("opacity",1e-6).remove(),_=oa.transition(M).style("opacity",1),w=Fi(e),S=s.selectAll(".domain").data([0]),E=(S.enter().append("path").attr("class","domain"),oa.transition(S)),k=e.copy(),A=this.__chart__||k;this.__chart__=k,x.append("line"),x.append("text");var N=x.select("line"),q=_.select("line"),T=M.select("text").text(g),C=x.select("text"),z=_.select("text");switch(r){case"bottom":n=bu,m.attr("y2",u),y.attr("x2",0).attr("y2",u),N.attr("y2",i),C.attr("y",Math.max(i,0)+o),q.attr("x2",0).attr("y2",i),z.attr("x",0).attr("y",Math.max(i,0)+o),T.attr("dy",".71em").style("text-anchor","middle"),E.attr("d","M"+w[0]+","+a+"V0H"+w[1]+"V"+a);break;case"top":n=bu,m.attr("y2",-u),y.attr("x2",0).attr("y2",-u),N.attr("y2",-i),C.attr("y",-(Math.max(i,0)+o)),q.attr("x2",0).attr("y2",-i),z.attr("x",0).attr("y",-(Math.max(i,0)+o)),T.attr("dy","0em").style("text-anchor","middle"),E.attr("d","M"+w[0]+","+-a+"V0H"+w[1]+"V"+-a);break;case"left":n=_u,m.attr("x2",-u),y.attr("x2",-u).attr("y2",0),N.attr("x2",-i),C.attr("x",-(Math.max(i,0)+o)),q.attr("x2",-i).attr("y2",0),z.attr("x",-(Math.max(i,0)+o)).attr("y",0),T.attr("dy",".32em").style("text-anchor","end"),E.attr("d","M"+-a+","+w[0]+"H0V"+w[1]+"H"+-a);break;case"right":n=_u,m.attr("x2",u),y.attr("x2",u).attr("y2",0),N.attr("x2",i),C.attr("x",Math.max(i,0)+o),q.attr("x2",i).attr("y2",0),z.attr("x",Math.max(i,0)+o).attr("y",0),T.attr("dy",".32em").style("text-anchor","start"),E.attr("d","M"+a+","+w[0]+"H0V"+w[1]+"H"+a)}if(e.ticks)x.call(n,A),_.call(n,k),b.call(n,k),m.call(n,A),y.call(n,k),v.call(n,k);else{var D=k.rangeBand()/2,j=function(n){return k(n)+D};x.call(n,j),_.call(n,j)}})}var t,e=oa.scale.linear(),r=cc,i=6,u=6,a=6,o=3,c=[10],l=null,f=0;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in lc?t+"":cc,n):r},n.ticks=function(){return arguments.length?(c=arguments,n):c},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t,e){if(!arguments.length)return i;var r=arguments.length-1;return i=+t,u=r>1?+e:i,a=r>0?+arguments[r]:i,n},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(t){return arguments.length?(f=+t,n):f},n};var cc="bottom",lc={top:1,right:1,bottom:1,left:1};oa.svg.brush=function(){function n(u){u.each(function(){var u,a=oa.select(this),l=a.selectAll(".background").data([0]),s=a.selectAll(".extent").data([0]),h=a.selectAll(".resize").data(f,String);a.style("pointer-events","all").on("mousedown.brush",i).on("touchstart.brush",i),l.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),s.enter().append("rect").attr("class","extent").style("cursor","move"),h.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return fc[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),h.style("display",n.empty()?"none":null),h.exit().remove(),o&&(u=Fi(o),l.attr("x",u[0]).attr("width",u[1]-u[0]),e(a)),c&&(u=Fi(c),l.attr("y",u[0]).attr("height",u[1]-u[0]),r(a)),t(a)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)][0]+","+s[+/^s/.test(n)][1]+")"})}function e(n){n.select(".extent").attr("x",s[0][0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1][0]-s[0][0])}function r(n){n.select(".extent").attr("y",s[0][1]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",s[1][1]-s[0][1])}function i(){function i(){var n=oa.event.changedTouches;return n?oa.touches(y,n)[0]:oa.mouse(y)}function f(){oa.event.keyCode==32&&(E||(m=null,k[0]-=s[1][0],k[1]-=s[1][1],E=2),l())}function h(){oa.event.keyCode==32&&2==E&&(k[0]+=s[1][0],k[1]+=s[1][1],E=0,l())}function g(){var n=i(),u=!1;v&&(n[0]+=v[0],n[1]+=v[1]),E||(oa.event.altKey?(m||(m=[(s[0][0]+s[1][0])/2,(s[0][1]+s[1][1])/2]),k[0]=s[+(n[0]<m[0])][0],k[1]=s[+(n[1]<m[1])][1]):m=null),w&&p(n,o,0)&&(e(b),u=!0),S&&p(n,c,1)&&(r(b),u=!0),u&&(t(b),x({type:"brush",mode:E?"move":"resize"}))}function p(n,t,e){var r,i,a=Fi(t),o=a[0],c=a[1],l=k[e],f=s[1][e]-s[0][e];return E&&(o-=l,c-=f+l),r=Math.max(o,Math.min(c,n[e])),E?i=(r+=l)+f:(m&&(l=Math.max(o,Math.min(c,2*m[e]-r))),r>l?(i=r,r=l):i=l),s[0][e]!==r||s[1][e]!==i?(u=null,s[0][e]=r,s[1][e]=i,!0):void 0}function d(){g(),b.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),oa.select("body").style("cursor",null),A.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),x({type:"brushend"}),l()}var m,v,y=this,M=oa.select(oa.event.target),x=a.of(y,arguments),b=oa.select(y),_=M.datum(),w=!/^(n|s)$/.test(_)&&o,S=!/^(e|w)$/.test(_)&&c,E=M.classed("extent"),k=i(),A=oa.select(la).on("mousemove.brush",g).on("mouseup.brush",d).on("touchmove.brush",g).on("touchend.brush",d).on("keydown.brush",f).on("keyup.brush",h);if(E)k[0]=s[0][0]-k[0],k[1]=s[0][1]-k[1];else if(_){var N=+/w$/.test(_),q=+/^n/.test(_);v=[s[1-N][0]-k[0],s[1-q][1]-k[1]],k[0]=s[N][0],k[1]=s[q][1]}else oa.event.altKey&&(m=k.slice());b.style("pointer-events","none").selectAll(".resize").style("display",null),oa.select("body").style("cursor",M.style("cursor")),x({type:"brushstart"}),g(),l()
-}var u,a=h(n,"brushstart","brush","brushend"),o=null,c=null,f=sc[0],s=[[0,0],[0,0]];return n.x=function(t){return arguments.length?(o=t,f=sc[!o<<1|!c],n):o},n.y=function(t){return arguments.length?(c=t,f=sc[!o<<1|!c],n):c},n.extent=function(t){var e,r,i,a,l;return arguments.length?(u=[[0,0],[0,0]],o&&(e=t[0],r=t[1],c&&(e=e[0],r=r[0]),u[0][0]=e,u[1][0]=r,o.invert&&(e=o(e),r=o(r)),e>r&&(l=e,e=r,r=l),s[0][0]=0|e,s[1][0]=0|r),c&&(i=t[0],a=t[1],o&&(i=i[1],a=a[1]),u[0][1]=i,u[1][1]=a,c.invert&&(i=c(i),a=c(a)),i>a&&(l=i,i=a,a=l),s[0][1]=0|i,s[1][1]=0|a),n):(t=u||s,o&&(e=t[0][0],r=t[1][0],u||(e=s[0][0],r=s[1][0],o.invert&&(e=o.invert(e),r=o.invert(r)),e>r&&(l=e,e=r,r=l))),c&&(i=t[0][1],a=t[1][1],u||(i=s[0][1],a=s[1][1],c.invert&&(i=c.invert(i),a=c.invert(a)),i>a&&(l=i,i=a,a=l))),o&&c?[[e,i],[r,a]]:o?[e,r]:c&&[i,a])},n.clear=function(){return u=null,s[0][0]=s[0][1]=s[1][0]=s[1][1]=0,n},n.empty=function(){return o&&s[0][0]===s[1][0]||c&&s[0][1]===s[1][1]},oa.rebind(n,a,"on")};var fc={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},sc=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]];oa.time={};var hc=Date,gc=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];Su.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){pc.setUTCDate.apply(this._,arguments)},setDay:function(){pc.setUTCDay.apply(this._,arguments)},setFullYear:function(){pc.setUTCFullYear.apply(this._,arguments)},setHours:function(){pc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){pc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){pc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){pc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){pc.setUTCSeconds.apply(this._,arguments)},setTime:function(){pc.setTime.apply(this._,arguments)}};var pc=Date.prototype,dc="%a %b %e %X %Y",mc="%m/%d/%Y",vc="%H:%M:%S",yc=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],Mc=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],xc=["January","February","March","April","May","June","July","August","September","October","November","December"],bc=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];oa.time.year=Eu(function(n){return n=oa.time.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),oa.time.years=oa.time.year.range,oa.time.years.utc=oa.time.year.utc.range,oa.time.day=Eu(function(n){var t=new hc(1970,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),oa.time.days=oa.time.day.range,oa.time.days.utc=oa.time.day.utc.range,oa.time.dayOfYear=function(n){var t=oa.time.year(n);return Math.floor((n-t-(n.getTimezoneOffset()-t.getTimezoneOffset())*6e4)/864e5)},gc.forEach(function(n,t){n=n.toLowerCase(),t=7-t;var e=oa.time[n]=Eu(function(n){return(n=oa.time.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+Math.floor(t)*7)},function(n){var e=oa.time.year(n).getDay();return Math.floor((oa.time.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});oa.time[n+"s"]=e.range,oa.time[n+"s"].utc=e.utc.range,oa.time[n+"OfYear"]=function(n){var e=oa.time.year(n).getDay();return Math.floor((oa.time.dayOfYear(n)+(e+t)%7)/7)}}),oa.time.week=oa.time.sunday,oa.time.weeks=oa.time.sunday.range,oa.time.weeks.utc=oa.time.sunday.utc.range,oa.time.weekOfYear=oa.time.sundayOfYear,oa.time.format=function(n){function t(t){for(var r,i,u,a=[],o=-1,c=0;++o<e;)n.charCodeAt(o)===37&&(a.push(n.substring(c,o)),(i=Nc[r=n.charAt(++o)])!=null&&(r=n.charAt(++o)),(u=qc[r])&&(r=u(t,null==i?"e"===r?" ":"0":i)),a.push(r),c=o+1);return a.push(n.substring(c,o)),a.join("")}var e=n.length;return t.parse=function(t){var e={y:1900,m:0,d:1,H:0,M:0,S:0,L:0},r=Au(e,n,t,0);if(r!=t.length)return null;"p"in e&&(e.H=e.H%12+e.p*12);var i=new hc;return i.setFullYear(e.y,e.m,e.d),i.setHours(e.H,e.M,e.S,e.L),i},t.toString=function(){return n},t};var _c=Nu(yc),wc=Nu(Mc),Sc=Nu(xc),Ec=qu(xc),kc=Nu(bc),Ac=qu(bc),Nc={"-":"",_:" ",0:"0"},qc={a:function(n){return Mc[n.getDay()]},A:function(n){return yc[n.getDay()]},b:function(n){return bc[n.getMonth()]},B:function(n){return xc[n.getMonth()]},c:oa.time.format(dc),d:function(n,t){return Tu(n.getDate(),t,2)},e:function(n,t){return Tu(n.getDate(),t,2)},H:function(n,t){return Tu(n.getHours(),t,2)},I:function(n,t){return Tu(n.getHours()%12||12,t,2)},j:function(n,t){return Tu(1+oa.time.dayOfYear(n),t,3)},L:function(n,t){return Tu(n.getMilliseconds(),t,3)},m:function(n,t){return Tu(n.getMonth()+1,t,2)},M:function(n,t){return Tu(n.getMinutes(),t,2)},p:function(n){return n.getHours()>=12?"PM":"AM"},S:function(n,t){return Tu(n.getSeconds(),t,2)},U:function(n,t){return Tu(oa.time.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Tu(oa.time.mondayOfYear(n),t,2)},x:oa.time.format(mc),X:oa.time.format(vc),y:function(n,t){return Tu(n.getFullYear()%100,t,2)},Y:function(n,t){return Tu(n.getFullYear()%1e4,t,4)},Z:$u,"%":function(){return"%"}},Tc={a:Cu,A:zu,b:Du,B:ju,c:Lu,d:Uu,e:Uu,H:Iu,I:Iu,L:Zu,m:Yu,M:Vu,p:Bu,S:Xu,x:Fu,X:Hu,y:Ru,Y:Pu},Cc=/^\s*\d+/,zc=oa.map({am:0,pm:1});oa.time.format.utc=function(n){function t(n){try{hc=Su;var t=new hc;return t._=n,e(t)}finally{hc=Date}}var e=oa.time.format(n);return t.parse=function(n){try{hc=Su;var t=e.parse(n);return t&&t._}finally{hc=Date}},t.toString=e.toString,t};var Dc=oa.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");oa.time.format.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Ju:Dc,Ju.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Ju.toString=Dc.toString,oa.time.second=Eu(function(n){return new hc(Math.floor(n/1e3)*1e3)},function(n,t){n.setTime(n.getTime()+Math.floor(t)*1e3)},function(n){return n.getSeconds()}),oa.time.seconds=oa.time.second.range,oa.time.seconds.utc=oa.time.second.utc.range,oa.time.minute=Eu(function(n){return new hc(Math.floor(n/6e4)*6e4)},function(n,t){n.setTime(n.getTime()+Math.floor(t)*6e4)},function(n){return n.getMinutes()}),oa.time.minutes=oa.time.minute.range,oa.time.minutes.utc=oa.time.minute.utc.range,oa.time.hour=Eu(function(n){var t=n.getTimezoneOffset()/60;return new hc((Math.floor(n/36e5-t)+t)*36e5)},function(n,t){n.setTime(n.getTime()+Math.floor(t)*36e5)},function(n){return n.getHours()}),oa.time.hours=oa.time.hour.range,oa.time.hours.utc=oa.time.hour.utc.range,oa.time.month=Eu(function(n){return n=oa.time.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),oa.time.months=oa.time.month.range,oa.time.months.utc=oa.time.month.utc.range;var jc=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Lc=[[oa.time.second,1],[oa.time.second,5],[oa.time.second,15],[oa.time.second,30],[oa.time.minute,1],[oa.time.minute,5],[oa.time.minute,15],[oa.time.minute,30],[oa.time.hour,1],[oa.time.hour,3],[oa.time.hour,6],[oa.time.hour,12],[oa.time.day,1],[oa.time.day,2],[oa.time.week,1],[oa.time.month,1],[oa.time.month,3],[oa.time.year,1]],Fc=[[oa.time.format("%Y"),jt],[oa.time.format("%B"),function(n){return n.getMonth()}],[oa.time.format("%b %d"),function(n){return n.getDate()!=1}],[oa.time.format("%a %d"),function(n){return n.getDay()&&n.getDate()!=1}],[oa.time.format("%I %p"),function(n){return n.getHours()}],[oa.time.format("%I:%M"),function(n){return n.getMinutes()}],[oa.time.format(":%S"),function(n){return n.getSeconds()}],[oa.time.format(".%L"),function(n){return n.getMilliseconds()}]],Hc=oa.scale.linear(),Pc=Wu(Fc);Lc.year=function(n,t){return Hc.domain(n.map(na)).ticks(t).map(Qu)},oa.time.scale=function(){return Gu(oa.scale.linear(),Lc,Pc)};var Rc=Lc.map(function(n){return[n[0].utc,n[1]]}),Oc=[[oa.time.format.utc("%Y"),jt],[oa.time.format.utc("%B"),function(n){return n.getUTCMonth()}],[oa.time.format.utc("%b %d"),function(n){return n.getUTCDate()!=1}],[oa.time.format.utc("%a %d"),function(n){return n.getUTCDay()&&n.getUTCDate()!=1}],[oa.time.format.utc("%I %p"),function(n){return n.getUTCHours()}],[oa.time.format.utc("%I:%M"),function(n){return n.getUTCMinutes()}],[oa.time.format.utc(":%S"),function(n){return n.getUTCSeconds()}],[oa.time.format.utc(".%L"),function(n){return n.getUTCMilliseconds()}]],Yc=Wu(Oc);return Rc.year=function(n,t){return Hc.domain(n.map(ea)).ticks(t).map(ta)},oa.time.scale.utc=function(){return Gu(oa.scale.linear(),Rc,Yc)},oa.text=function(){return oa.xhr.apply(oa,arguments).response(ra)},oa.json=function(n,t){return oa.xhr(n,"application/json",t).response(ia)},oa.html=function(n,t){return oa.xhr(n,"text/html",t).response(ua)},oa.xml=function(){return oa.xhr.apply(oa,arguments).response(aa)},oa}(); \ No newline at end of file
diff --git a/horizon/static/horizon/lib/hogan-2.0.0.js b/horizon/static/horizon/lib/hogan-2.0.0.js
deleted file mode 100644
index 43a67074..00000000
--- a/horizon/static/horizon/lib/hogan-2.0.0.js
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright 2011 Twitter, 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.
- */
-
-
-
-var Hogan = {};
-
-(function (Hogan, useArrayBuffer) {
- Hogan.Template = function (renderFunc, text, compiler, options) {
- this.r = renderFunc || this.r;
- this.c = compiler;
- this.options = options;
- this.text = text || '';
- this.buf = (useArrayBuffer) ? [] : '';
- }
-
- Hogan.Template.prototype = {
- // render: replaced by generated code.
- r: function (context, partials, indent) { return ''; },
-
- // variable escaping
- v: hoganEscape,
-
- // triple stache
- t: coerceToString,
-
- render: function render(context, partials, indent) {
- return this.ri([context], partials || {}, indent);
- },
-
- // render internal -- a hook for overrides that catches partials too
- ri: function (context, partials, indent) {
- return this.r(context, partials, indent);
- },
-
- // tries to find a partial in the curent scope and render it
- rp: function(name, context, partials, indent) {
- var partial = partials[name];
-
- if (!partial) {
- return '';
- }
-
- if (this.c && typeof partial == 'string') {
- partial = this.c.compile(partial, this.options);
- }
-
- return partial.ri(context, partials, indent);
- },
-
- // render a section
- rs: function(context, partials, section) {
- var tail = context[context.length - 1];
-
- if (!isArray(tail)) {
- section(context, partials, this);
- return;
- }
-
- for (var i = 0; i < tail.length; i++) {
- context.push(tail[i]);
- section(context, partials, this);
- context.pop();
- }
- },
-
- // maybe start a section
- s: function(val, ctx, partials, inverted, start, end, tags) {
- var pass;
-
- if (isArray(val) && val.length === 0) {
- return false;
- }
-
- if (typeof val == 'function') {
- val = this.ls(val, ctx, partials, inverted, start, end, tags);
- }
-
- pass = (val === '') || !!val;
-
- if (!inverted && pass && ctx) {
- ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]);
- }
-
- return pass;
- },
-
- // find values with dotted names
- d: function(key, ctx, partials, returnFound) {
- var names = key.split('.'),
- val = this.f(names[0], ctx, partials, returnFound),
- cx = null;
-
- if (key === '.' && isArray(ctx[ctx.length - 2])) {
- return ctx[ctx.length - 1];
- }
-
- for (var i = 1; i < names.length; i++) {
- if (val && typeof val == 'object' && names[i] in val) {
- cx = val;
- val = val[names[i]];
- } else {
- val = '';
- }
- }
-
- if (returnFound && !val) {
- return false;
- }
-
- if (!returnFound && typeof val == 'function') {
- ctx.push(cx);
- val = this.lv(val, ctx, partials);
- ctx.pop();
- }
-
- return val;
- },
-
- // find values with normal names
- f: function(key, ctx, partials, returnFound) {
- var val = false,
- v = null,
- found = false;
-
- for (var i = ctx.length - 1; i >= 0; i--) {
- v = ctx[i];
- if (v && typeof v == 'object' && key in v) {
- val = v[key];
- found = true;
- break;
- }
- }
-
- if (!found) {
- return (returnFound) ? false : "";
- }
-
- if (!returnFound && typeof val == 'function') {
- val = this.lv(val, ctx, partials);
- }
-
- return val;
- },
-
- // higher order templates
- ho: function(val, cx, partials, text, tags) {
- var compiler = this.c;
- var options = this.options;
- options.delimiters = tags;
- var text = val.call(cx, text);
- text = (text == null) ? String(text) : text.toString();
- this.b(compiler.compile(text, options).render(cx, partials));
- return false;
- },
-
- // template result buffering
- b: (useArrayBuffer) ? function(s) { this.buf.push(s); } :
- function(s) { this.buf += s; },
- fl: (useArrayBuffer) ? function() { var r = this.buf.join(''); this.buf = []; return r; } :
- function() { var r = this.buf; this.buf = ''; return r; },
-
- // lambda replace section
- ls: function(val, ctx, partials, inverted, start, end, tags) {
- var cx = ctx[ctx.length - 1],
- t = null;
-
- if (!inverted && this.c && val.length > 0) {
- return this.ho(val, cx, partials, this.text.substring(start, end), tags);
- }
-
- t = val.call(cx);
-
- if (typeof t == 'function') {
- if (inverted) {
- return true;
- } else if (this.c) {
- return this.ho(t, cx, partials, this.text.substring(start, end), tags);
- }
- }
-
- return t;
- },
-
- // lambda replace variable
- lv: function(val, ctx, partials) {
- var cx = ctx[ctx.length - 1];
- var result = val.call(cx);
-
- if (typeof result == 'function') {
- result = coerceToString(result.call(cx));
- if (this.c && ~result.indexOf("{\u007B")) {
- return this.c.compile(result, this.options).render(cx, partials);
- }
- }
-
- return coerceToString(result);
- }
-
- };
-
- var rAmp = /&/g,
- rLt = /</g,
- rGt = />/g,
- rApos =/\'/g,
- rQuot = /\"/g,
- hChars =/[&<>\"\']/;
-
-
- function coerceToString(val) {
- return String((val === null || val === undefined) ? '' : val);
- }
-
- function hoganEscape(str) {
- str = coerceToString(str);
- return hChars.test(str) ?
- str
- .replace(rAmp,'&amp;')
- .replace(rLt,'&lt;')
- .replace(rGt,'&gt;')
- .replace(rApos,'&#39;')
- .replace(rQuot, '&quot;') :
- str;
- }
-
- var isArray = Array.isArray || function(a) {
- return Object.prototype.toString.call(a) === '[object Array]';
- };
-
-})(typeof exports !== 'undefined' ? exports : Hogan);
-
-
-
-
-(function (Hogan) {
- // Setup regex assignments
- // remove whitespace according to Mustache spec
- var rIsWhitespace = /\S/,
- rQuot = /\"/g,
- rNewline = /\n/g,
- rCr = /\r/g,
- rSlash = /\\/g,
- tagTypes = {
- '#': 1, '^': 2, '/': 3, '!': 4, '>': 5,
- '<': 6, '=': 7, '_v': 8, '{': 9, '&': 10
- };
-
- Hogan.scan = function scan(text, delimiters) {
- var len = text.length,
- IN_TEXT = 0,
- IN_TAG_TYPE = 1,
- IN_TAG = 2,
- state = IN_TEXT,
- tagType = null,
- tag = null,
- buf = '',
- tokens = [],
- seenTag = false,
- i = 0,
- lineStart = 0,
- otag = '{{',
- ctag = '}}';
-
- function addBuf() {
- if (buf.length > 0) {
- tokens.push(new String(buf));
- buf = '';
- }
- }
-
- function lineIsWhitespace() {
- var isAllWhitespace = true;
- for (var j = lineStart; j < tokens.length; j++) {
- isAllWhitespace =
- (tokens[j].tag && tagTypes[tokens[j].tag] < tagTypes['_v']) ||
- (!tokens[j].tag && tokens[j].match(rIsWhitespace) === null);
- if (!isAllWhitespace) {
- return false;
- }
- }
-
- return isAllWhitespace;
- }
-
- function filterLine(haveSeenTag, noNewLine) {
- addBuf();
-
- if (haveSeenTag && lineIsWhitespace()) {
- for (var j = lineStart, next; j < tokens.length; j++) {
- if (!tokens[j].tag) {
- if ((next = tokens[j+1]) && next.tag == '>') {
- // set indent to token value
- next.indent = tokens[j].toString()
- }
- tokens.splice(j, 1);
- }
- }
- } else if (!noNewLine) {
- tokens.push({tag:'\n'});
- }
-
- seenTag = false;
- lineStart = tokens.length;
- }
-
- function changeDelimiters(text, index) {
- var close = '=' + ctag,
- closeIndex = text.indexOf(close, index),
- delimiters = trim(
- text.substring(text.indexOf('=', index) + 1, closeIndex)
- ).split(' ');
-
- otag = delimiters[0];
- ctag = delimiters[1];
-
- return closeIndex + close.length - 1;
- }
-
- if (delimiters) {
- delimiters = delimiters.split(' ');
- otag = delimiters[0];
- ctag = delimiters[1];
- }
-
- for (i = 0; i < len; i++) {
- if (state == IN_TEXT) {
- if (tagChange(otag, text, i)) {
- --i;
- addBuf();
- state = IN_TAG_TYPE;
- } else {
- if (text.charAt(i) == '\n') {
- filterLine(seenTag);
- } else {
- buf += text.charAt(i);
- }
- }
- } else if (state == IN_TAG_TYPE) {
- i += otag.length - 1;
- tag = tagTypes[text.charAt(i + 1)];
- tagType = tag ? text.charAt(i + 1) : '_v';
- if (tagType == '=') {
- i = changeDelimiters(text, i);
- state = IN_TEXT;
- } else {
- if (tag) {
- i++;
- }
- state = IN_TAG;
- }
- seenTag = i;
- } else {
- if (tagChange(ctag, text, i)) {
- tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag,
- i: (tagType == '/') ? seenTag - ctag.length : i + otag.length});
- buf = '';
- i += ctag.length - 1;
- state = IN_TEXT;
- if (tagType == '{') {
- if (ctag == '}}') {
- i++;
- } else {
- cleanTripleStache(tokens[tokens.length - 1]);
- }
- }
- } else {
- buf += text.charAt(i);
- }
- }
- }
-
- filterLine(seenTag, true);
-
- return tokens;
- }
-
- function cleanTripleStache(token) {
- if (token.n.substr(token.n.length - 1) === '}') {
- token.n = token.n.substring(0, token.n.length - 1);
- }
- }
-
- function trim(s) {
- if (s.trim) {
- return s.trim();
- }
-
- return s.replace(/^\s*|\s*$/g, '');
- }
-
- function tagChange(tag, text, index) {
- if (text.charAt(index) != tag.charAt(0)) {
- return false;
- }
-
- for (var i = 1, l = tag.length; i < l; i++) {
- if (text.charAt(index + i) != tag.charAt(i)) {
- return false;
- }
- }
-
- return true;
- }
-
- function buildTree(tokens, kind, stack, customTags) {
- var instructions = [],
- opener = null,
- token = null;
-
- while (tokens.length > 0) {
- token = tokens.shift();
- if (token.tag == '#' || token.tag == '^' || isOpener(token, customTags)) {
- stack.push(token);
- token.nodes = buildTree(tokens, token.tag, stack, customTags);
- instructions.push(token);
- } else if (token.tag == '/') {
- if (stack.length === 0) {
- throw new Error('Closing tag without opener: /' + token.n);
- }
- opener = stack.pop();
- if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) {
- throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n);
- }
- opener.end = token.i;
- return instructions;
- } else {
- instructions.push(token);
- }
- }
-
- if (stack.length > 0) {
- throw new Error('missing closing tag: ' + stack.pop().n);
- }
-
- return instructions;
- }
-
- function isOpener(token, tags) {
- for (var i = 0, l = tags.length; i < l; i++) {
- if (tags[i].o == token.n) {
- token.tag = '#';
- return true;
- }
- }
- }
-
- function isCloser(close, open, tags) {
- for (var i = 0, l = tags.length; i < l; i++) {
- if (tags[i].c == close && tags[i].o == open) {
- return true;
- }
- }
- }
-
- Hogan.generate = function (tree, text, options) {
- var code = 'var _=this;_.b(i=i||"");' + walk(tree) + 'return _.fl();';
- if (options.asString) {
- return 'function(c,p,i){' + code + ';}';
- }
-
- return new Hogan.Template(new Function('c', 'p', 'i', code), text, Hogan, options);
- }
-
- function esc(s) {
- return s.replace(rSlash, '\\\\')
- .replace(rQuot, '\\\"')
- .replace(rNewline, '\\n')
- .replace(rCr, '\\r');
- }
-
- function chooseMethod(s) {
- return (~s.indexOf('.')) ? 'd' : 'f';
- }
-
- function walk(tree) {
- var code = '';
- for (var i = 0, l = tree.length; i < l; i++) {
- var tag = tree[i].tag;
- if (tag == '#') {
- code += section(tree[i].nodes, tree[i].n, chooseMethod(tree[i].n),
- tree[i].i, tree[i].end, tree[i].otag + " " + tree[i].ctag);
- } else if (tag == '^') {
- code += invertedSection(tree[i].nodes, tree[i].n,
- chooseMethod(tree[i].n));
- } else if (tag == '<' || tag == '>') {
- code += partial(tree[i]);
- } else if (tag == '{' || tag == '&') {
- code += tripleStache(tree[i].n, chooseMethod(tree[i].n));
- } else if (tag == '\n') {
- code += text('"\\n"' + (tree.length-1 == i ? '' : ' + i'));
- } else if (tag == '_v') {
- code += variable(tree[i].n, chooseMethod(tree[i].n));
- } else if (tag === undefined) {
- code += text('"' + esc(tree[i]) + '"');
- }
- }
- return code;
- }
-
- function section(nodes, id, method, start, end, tags) {
- return 'if(_.s(_.' + method + '("' + esc(id) + '",c,p,1),' +
- 'c,p,0,' + start + ',' + end + ',"' + tags + '")){' +
- '_.rs(c,p,' +
- 'function(c,p,_){' +
- walk(nodes) +
- '});c.pop();}';
- }
-
- function invertedSection(nodes, id, method) {
- return 'if(!_.s(_.' + method + '("' + esc(id) + '",c,p,1),c,p,1,0,0,"")){' +
- walk(nodes) +
- '};';
- }
-
- function partial(tok) {
- return '_.b(_.rp("' + esc(tok.n) + '",c,p,"' + (tok.indent || '') + '"));';
- }
-
- function tripleStache(id, method) {
- return '_.b(_.t(_.' + method + '("' + esc(id) + '",c,p,0)));';
- }
-
- function variable(id, method) {
- return '_.b(_.v(_.' + method + '("' + esc(id) + '",c,p,0)));';
- }
-
- function text(id) {
- return '_.b(' + id + ');';
- }
-
- Hogan.parse = function(tokens, text, options) {
- options = options || {};
- return buildTree(tokens, '', [], options.sectionTags || []);
- },
-
- Hogan.cache = {};
-
- Hogan.compile = function(text, options) {
- // options
- //
- // asString: false (default)
- //
- // sectionTags: [{o: '_foo', c: 'foo'}]
- // An array of object with o and c fields that indicate names for custom
- // section tags. The example above allows parsing of {{_foo}}{{/foo}}.
- //
- // delimiters: A string that overrides the default delimiters.
- // Example: "<% %>"
- //
- options = options || {};
-
- var key = text + '||' + !!options.asString;
-
- var t = this.cache[key];
-
- if (t) {
- return t;
- }
-
- t = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options);
- return this.cache[key] = t;
- };
-})(typeof exports !== 'undefined' ? exports : Hogan);
-
diff --git a/horizon/static/horizon/lib/jquery/jquery-ui-1.9.2.custom.min.js b/horizon/static/horizon/lib/jquery/jquery-ui-1.9.2.custom.min.js
deleted file mode 100755
index 761705c0..00000000
--- a/horizon/static/horizon/lib/jquery/jquery-ui-1.9.2.custom.min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/*! jQuery UI - v1.9.2 - 2013-01-11
-* http://jqueryui.com
-* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.selectable.js, jquery.ui.sortable.js
-* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */
-
-(function(e,t){function i(t,n){var r,i,o,u=t.nodeName.toLowerCase();return"area"===u?(r=t.parentNode,i=r.name,!t.href||!i||r.nodeName.toLowerCase()!=="map"?!1:(o=e("img[usemap=#"+i+"]")[0],!!o&&s(o))):(/input|select|textarea|button|object/.test(u)?!t.disabled:"a"===u?t.href||n:n)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().andSelf().filter(function(){return e.css(this,"visibility")==="hidden"}).length}var n=0,r=/^ui-id-\d+$/;e.ui=e.ui||{};if(e.ui.version)return;e.extend(e.ui,{version:"1.9.2",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({_focus:e.fn.focus,focus:function(t,n){return typeof t=="number"?this.each(function(){var r=this;setTimeout(function(){e(r).focus(),n&&n.call(r)},t)}):this._focus.apply(this,arguments)},scrollParent:function(){var t;return e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?t=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):t=this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(n){if(n!==t)return this.css("zIndex",n);if(this.length){var r=e(this[0]),i,s;while(r.length&&r[0]!==document){i=r.css("position");if(i==="absolute"||i==="relative"||i==="fixed"){s=parseInt(r.css("zIndex"),10);if(!isNaN(s)&&s!==0)return s}r=r.parent()}}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++n)})},removeUniqueId:function(){return this.each(function(){r.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(n){return!!e.data(n,t)}}):function(t,n,r){return!!e.data(t,r[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),r=isNaN(n);return(r||n>=0)&&i(t,!r)}}),e(function(){var t=document.body,n=t.appendChild(n=document.createElement("div"));n.offsetHeight,e.extend(n.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),e.support.minHeight=n.offsetHeight===100,e.support.selectstart="onselectstart"in n,t.removeChild(n).style.display="none"}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(n,r){function u(t,n,r,s){return e.each(i,function(){n-=parseFloat(e.css(t,"padding"+this))||0,r&&(n-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(n-=parseFloat(e.css(t,"margin"+this))||0)}),n}var i=r==="Width"?["Left","Right"]:["Top","Bottom"],s=r.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+r]=function(n){return n===t?o["inner"+r].call(this):this.each(function(){e(this).css(s,u(this,n)+"px")})},e.fn["outer"+r]=function(t,n){return typeof t!="number"?o["outer"+r].call(this,t):this.each(function(){e(this).css(s,u(this,t,!0,n)+"px")})}}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(n){return arguments.length?t.call(this,e.camelCase(n)):t.call(this)}}(e.fn.removeData)),function(){var t=/msie ([\w.]+)/.exec(navigator.userAgent.toLowerCase())||[];e.ui.ie=t.length?!0:!1,e.ui.ie6=parseFloat(t[1],10)===6}(),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,n,r){var i,s=e.ui[t].prototype;for(i in r)s.plugins[i]=s.plugins[i]||[],s.plugins[i].push([n,r[i]])},call:function(e,t,n){var r,i=e.plugins[t];if(!i||!e.element[0].parentNode||e.element[0].parentNode.nodeType===11)return;for(r=0;r<i.length;r++)e.options[i[r][0]]&&i[r][1].apply(e.element,n)}},contains:e.contains,hasScroll:function(t,n){if(e(t).css("overflow")==="hidden")return!1;var r=n&&n==="left"?"scrollLeft":"scrollTop",i=!1;return t[r]>0?!0:(t[r]=1,i=t[r]>0,t[r]=0,i)},isOverAxis:function(e,t,n){return e>t&&e<t+n},isOver:function(t,n,r,i,s,o){return e.ui.isOverAxis(t,r,s)&&e.ui.isOverAxis(n,i,o)}})})(jQuery);(function(e,t){var n=0,r=Array.prototype.slice,i=e.cleanData;e.cleanData=function(t){for(var n=0,r;(r=t[n])!=null;n++)try{e(r).triggerHandler("remove")}catch(s){}i(t)},e.widget=function(t,n,r){var i,s,o,u,a=t.split(".")[0];t=t.split(".")[1],i=a+"-"+t,r||(r=n,n=e.Widget),e.expr[":"][i.toLowerCase()]=function(t){return!!e.data(t,i)},e[a]=e[a]||{},s=e[a][t],o=e[a][t]=function(e,t){if(!this._createWidget)return new o(e,t);arguments.length&&this._createWidget(e,t)},e.extend(o,s,{version:r.version,_proto:e.extend({},r),_childConstructors:[]}),u=new n,u.options=e.widget.extend({},u.options),e.each(r,function(t,i){e.isFunction(i)&&(r[t]=function(){var e=function(){return n.prototype[t].apply(this,arguments)},r=function(e){return n.prototype[t].apply(this,e)};return function(){var t=this._super,n=this._superApply,s;return this._super=e,this._superApply=r,s=i.apply(this,arguments),this._super=t,this._superApply=n,s}}())}),o.prototype=e.widget.extend(u,{widgetEventPrefix:s?u.widgetEventPrefix:t},r,{constructor:o,namespace:a,widgetName:t,widgetBaseClass:i,widgetFullName:i}),s?(e.each(s._childConstructors,function(t,n){var r=n.prototype;e.widget(r.namespace+"."+r.widgetName,o,n._proto)}),delete s._childConstructors):n._childConstructors.push(o),e.widget.bridge(t,o)},e.widget.extend=function(n){var i=r.call(arguments,1),s=0,o=i.length,u,a;for(;s<o;s++)for(u in i[s])a=i[s][u],i[s].hasOwnProperty(u)&&a!==t&&(e.isPlainObject(a)?n[u]=e.isPlainObject(n[u])?e.widget.extend({},n[u],a):e.widget.extend({},a):n[u]=a);return n},e.widget.bridge=function(n,i){var s=i.prototype.widgetFullName||n;e.fn[n]=function(o){var u=typeof o=="string",a=r.call(arguments,1),f=this;return o=!u&&a.length?e.widget.extend.apply(null,[o].concat(a)):o,u?this.each(function(){var r,i=e.data(this,s);if(!i)return e.error("cannot call methods on "+n+" prior to initialization; "+"attempted to call method '"+o+"'");if(!e.isFunction(i[o])||o.charAt(0)==="_")return e.error("no such method '"+o+"' for "+n+" widget instance");r=i[o].apply(i,a);if(r!==i&&r!==t)return f=r&&r.jquery?f.pushStack(r.get()):r,!1}):this.each(function(){var t=e.data(this,s);t?t.option(o||{})._init():e.data(this,s,new i(o,this))}),f}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,r){r=e(r||this.defaultElement||this)[0],this.element=e(r),this.uuid=n++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),r!==this&&(e.data(r,this.widgetName,this),e.data(r,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===r&&this.destroy()}}),this.document=e(r.style?r.ownerDocument:r.document||r),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(n,r){var i=n,s,o,u;if(arguments.length===0)return e.widget.extend({},this.options);if(typeof n=="string"){i={},s=n.split("."),n=s.shift();if(s.length){o=i[n]=e.widget.extend({},this.options[n]);for(u=0;u<s.length-1;u++)o[s[u]]=o[s[u]]||{},o=o[s[u]];n=s.pop();if(r===t)return o[n]===t?null:o[n];o[n]=r}else{if(r===t)return this.options[n]===t?null:this.options[n];i[n]=r}}return this._setOptions(i),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,e==="disabled"&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(t,n,r){var i,s=this;typeof t!="boolean"&&(r=n,n=t,t=!1),r?(n=i=e(n),this.bindings=this.bindings.add(n)):(r=n,n=this.element,i=this.widget()),e.each(r,function(r,o){function u(){if(!t&&(s.options.disabled===!0||e(this).hasClass("ui-state-disabled")))return;return(typeof o=="string"?s[o]:o).apply(s,arguments)}typeof o!="string"&&(u.guid=o.guid=o.guid||u.guid||e.guid++);var a=r.match(/^(\w+)\s*(.*)$/),f=a[1]+s.eventNamespace,l=a[2];l?i.delegate(l,f,u):n.bind(f,u)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function n(){return(typeof e=="string"?r[e]:e).apply(r,arguments)}var r=this;return setTimeout(n,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,n,r){var i,s,o=this.options[t];r=r||{},n=e.Event(n),n.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),n.target=this.element[0],s=n.originalEvent;if(s)for(i in s)i in n||(n[i]=s[i]);return this.element.trigger(n,r),!(e.isFunction(o)&&o.apply(this.element[0],[n].concat(r))===!1||n.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,n){e.Widget.prototype["_"+t]=function(r,i,s){typeof i=="string"&&(i={effect:i});var o,u=i?i===!0||typeof i=="number"?n:i.effect||n:t;i=i||{},typeof i=="number"&&(i={duration:i}),o=!e.isEmptyObject(i),i.complete=s,i.delay&&r.delay(i.delay),o&&e.effects&&(e.effects.effect[u]||e.uiBackCompat!==!1&&e.effects[u])?r[t](i):u!==t&&r[u]?r[u](i.duration,i.easing,s):r.queue(function(n){e(this)[t](),s&&s.call(r[0]),n()})}}),e.uiBackCompat!==!1&&(e.Widget.prototype._getCreateOptions=function(){return e.metadata&&e.metadata.get(this.element[0])[this.widgetName]})})(jQuery);(function(e,t){var n=!1;e(document).mouseup(function(e){n=!1}),e.widget("ui.mouse",{version:"1.9.2",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(n){if(!0===e.data(n.target,t.widgetName+".preventClickEvent"))return e.removeData(n.target,t.widgetName+".preventClickEvent"),n.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(n)return;this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var r=this,i=t.which===1,s=typeof this.options.cancel=="string"&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;if(!i||s||!this._mouseCapture(t))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){r.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)){this._mouseStarted=this._mouseStart(t)!==!1;if(!this._mouseStarted)return t.preventDefault(),!0}return!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return r._mouseMove(e)},this._mouseUpDelegate=function(e){return r._mouseUp(e)},e(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),n=!0,!0},_mouseMove:function(t){return!e.ui.ie||document.documentMode>=9||!!t.button?this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted):this._mouseUp(t)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(e){return this.mouseDelayMet},_mouseStart:function(e){},_mouseDrag:function(e){},_mouseStop:function(e){},_mouseCapture:function(e){return!0}})})(jQuery);(function(e,t){function h(e,t,n){return[parseInt(e[0],10)*(l.test(e[0])?t/100:1),parseInt(e[1],10)*(l.test(e[1])?n/100:1)]}function p(t,n){return parseInt(e.css(t,n),10)||0}e.ui=e.ui||{};var n,r=Math.max,i=Math.abs,s=Math.round,o=/left|center|right/,u=/top|center|bottom/,a=/[\+\-]\d+%?/,f=/^\w+/,l=/%$/,c=e.fn.position;e.position={scrollbarWidth:function(){if(n!==t)return n;var r,i,s=e("<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=s.children()[0];return e("body").append(s),r=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,r===i&&(i=s[0].clientWidth),s.remove(),n=r-i},getScrollInfo:function(t){var n=t.isWindow?"":t.element.css("overflow-x"),r=t.isWindow?"":t.element.css("overflow-y"),i=n==="scroll"||n==="auto"&&t.width<t.element[0].scrollWidth,s=r==="scroll"||r==="auto"&&t.height<t.element[0].scrollHeight;return{width:i?e.position.scrollbarWidth():0,height:s?e.position.scrollbarWidth():0}},getWithinInfo:function(t){var n=e(t||window),r=e.isWindow(n[0]);return{element:n,isWindow:r,offset:n.offset()||{left:0,top:0},scrollLeft:n.scrollLeft(),scrollTop:n.scrollTop(),width:r?n.width():n.outerWidth(),height:r?n.height():n.outerHeight()}}},e.fn.position=function(t){if(!t||!t.of)return c.apply(this,arguments);t=e.extend({},t);var n,l,d,v,m,g=e(t.of),y=e.position.getWithinInfo(t.within),b=e.position.getScrollInfo(y),w=g[0],E=(t.collision||"flip").split(" "),S={};return w.nodeType===9?(l=g.width(),d=g.height(),v={top:0,left:0}):e.isWindow(w)?(l=g.width(),d=g.height(),v={top:g.scrollTop(),left:g.scrollLeft()}):w.preventDefault?(t.at="left top",l=d=0,v={top:w.pageY,left:w.pageX}):(l=g.outerWidth(),d=g.outerHeight(),v=g.offset()),m=e.extend({},v),e.each(["my","at"],function(){var e=(t[this]||"").split(" "),n,r;e.length===1&&(e=o.test(e[0])?e.concat(["center"]):u.test(e[0])?["center"].concat(e):["center","center"]),e[0]=o.test(e[0])?e[0]:"center",e[1]=u.test(e[1])?e[1]:"center",n=a.exec(e[0]),r=a.exec(e[1]),S[this]=[n?n[0]:0,r?r[0]:0],t[this]=[f.exec(e[0])[0],f.exec(e[1])[0]]}),E.length===1&&(E[1]=E[0]),t.at[0]==="right"?m.left+=l:t.at[0]==="center"&&(m.left+=l/2),t.at[1]==="bottom"?m.top+=d:t.at[1]==="center"&&(m.top+=d/2),n=h(S.at,l,d),m.left+=n[0],m.top+=n[1],this.each(function(){var o,u,a=e(this),f=a.outerWidth(),c=a.outerHeight(),w=p(this,"marginLeft"),x=p(this,"marginTop"),T=f+w+p(this,"marginRight")+b.width,N=c+x+p(this,"marginBottom")+b.height,C=e.extend({},m),k=h(S.my,a.outerWidth(),a.outerHeight());t.my[0]==="right"?C.left-=f:t.my[0]==="center"&&(C.left-=f/2),t.my[1]==="bottom"?C.top-=c:t.my[1]==="center"&&(C.top-=c/2),C.left+=k[0],C.top+=k[1],e.support.offsetFractions||(C.left=s(C.left),C.top=s(C.top)),o={marginLeft:w,marginTop:x},e.each(["left","top"],function(r,i){e.ui.position[E[r]]&&e.ui.position[E[r]][i](C,{targetWidth:l,targetHeight:d,elemWidth:f,elemHeight:c,collisionPosition:o,collisionWidth:T,collisionHeight:N,offset:[n[0]+k[0],n[1]+k[1]],my:t.my,at:t.at,within:y,elem:a})}),e.fn.bgiframe&&a.bgiframe(),t.using&&(u=function(e){var n=v.left-C.left,s=n+l-f,o=v.top-C.top,u=o+d-c,h={target:{element:g,left:v.left,top:v.top,width:l,height:d},element:{element:a,left:C.left,top:C.top,width:f,height:c},horizontal:s<0?"left":n>0?"right":"center",vertical:u<0?"top":o>0?"bottom":"middle"};l<f&&i(n+s)<l&&(h.horizontal="center"),d<c&&i(o+u)<d&&(h.vertical="middle"),r(i(n),i(s))>r(i(o),i(u))?h.important="horizontal":h.important="vertical",t.using.call(this,e,h)}),a.offset(e.extend(C,{using:u}))})},e.ui.position={fit:{left:function(e,t){var n=t.within,i=n.isWindow?n.scrollLeft:n.offset.left,s=n.width,o=e.left-t.collisionPosition.marginLeft,u=i-o,a=o+t.collisionWidth-s-i,f;t.collisionWidth>s?u>0&&a<=0?(f=e.left+u+t.collisionWidth-s-i,e.left+=u-f):a>0&&u<=0?e.left=i:u>a?e.left=i+s-t.collisionWidth:e.left=i:u>0?e.left+=u:a>0?e.left-=a:e.left=r(e.left-o,e.left)},top:function(e,t){var n=t.within,i=n.isWindow?n.scrollTop:n.offset.top,s=t.within.height,o=e.top-t.collisionPosition.marginTop,u=i-o,a=o+t.collisionHeight-s-i,f;t.collisionHeight>s?u>0&&a<=0?(f=e.top+u+t.collisionHeight-s-i,e.top+=u-f):a>0&&u<=0?e.top=i:u>a?e.top=i+s-t.collisionHeight:e.top=i:u>0?e.top+=u:a>0?e.top-=a:e.top=r(e.top-o,e.top)}},flip:{left:function(e,t){var n=t.within,r=n.offset.left+n.scrollLeft,s=n.width,o=n.isWindow?n.scrollLeft:n.offset.left,u=e.left-t.collisionPosition.marginLeft,a=u-o,f=u+t.collisionWidth-s-o,l=t.my[0]==="left"?-t.elemWidth:t.my[0]==="right"?t.elemWidth:0,c=t.at[0]==="left"?t.targetWidth:t.at[0]==="right"?-t.targetWidth:0,h=-2*t.offset[0],p,d;if(a<0){p=e.left+l+c+h+t.collisionWidth-s-r;if(p<0||p<i(a))e.left+=l+c+h}else if(f>0){d=e.left-t.collisionPosition.marginLeft+l+c+h-o;if(d>0||i(d)<f)e.left+=l+c+h}},top:function(e,t){var n=t.within,r=n.offset.top+n.scrollTop,s=n.height,o=n.isWindow?n.scrollTop:n.offset.top,u=e.top-t.collisionPosition.marginTop,a=u-o,f=u+t.collisionHeight-s-o,l=t.my[1]==="top",c=l?-t.elemHeight:t.my[1]==="bottom"?t.elemHeight:0,h=t.at[1]==="top"?t.targetHeight:t.at[1]==="bottom"?-t.targetHeight:0,p=-2*t.offset[1],d,v;a<0?(v=e.top+c+h+p+t.collisionHeight-s-r,e.top+c+h+p>a&&(v<0||v<i(a))&&(e.top+=c+h+p)):f>0&&(d=e.top-t.collisionPosition.marginTop+c+h+p-o,e.top+c+h+p>f&&(d>0||i(d)<f)&&(e.top+=c+h+p))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,n,r,i,s,o=document.getElementsByTagName("body")[0],u=document.createElement("div");t=document.createElement(o?"div":"body"),r={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},o&&e.extend(r,{position:"absolute",left:"-1000px",top:"-1000px"});for(s in r)t.style[s]=r[s];t.appendChild(u),n=o||document.documentElement,n.insertBefore(t,n.firstChild),u.style.cssText="position: absolute; left: 10.7432222px;",i=e(u).offset().left,e.support.offsetFractions=i>10&&i<11,t.innerHTML="",n.removeChild(t)}(),e.uiBackCompat!==!1&&function(e){var n=e.fn.position;e.fn.position=function(r){if(!r||!r.offset)return n.call(this,r);var i=r.offset.split(" "),s=r.at.split(" ");return i.length===1&&(i[1]=i[0]),/^\d/.test(i[0])&&(i[0]="+"+i[0]),/^\d/.test(i[1])&&(i[1]="+"+i[1]),s.length===1&&(/left|center|right/.test(s[0])?s[1]="center":(s[1]=s[0],s[0]="center")),n.call(this,e.extend(r,{at:s[0]+i[0]+" "+s[1]+i[1],offset:t}))}}(jQuery)})(jQuery);(function(e,t){e.widget("ui.draggable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(t){var n=this.options;return this.helper||n.disabled||e(t.target).is(".ui-resizable-handle")?!1:(this.handle=this._getHandle(t),this.handle?(e(n.iframeFix===!0?"iframe":n.iframeFix).each(function(){e('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var n=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),n.containment&&this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,n){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute");if(!n){var r=this._uiHash();if(this._trigger("drag",t,r)===!1)return this._mouseUp({}),!1;this.position=r.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";return e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var n=!1;e.ui.ddmanager&&!this.options.dropBehaviour&&(n=e.ui.ddmanager.drop(this,t)),this.dropped&&(n=this.dropped,this.dropped=!1);var r=this.element[0],i=!1;while(r&&(r=r.parentNode))r==document&&(i=!0);if(!i&&this.options.helper==="original")return!1;if(this.options.revert=="invalid"&&!n||this.options.revert=="valid"&&n||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,n)){var s=this;e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){s._trigger("stop",t)!==!1&&s._clear()})}else this._trigger("stop",t)!==!1&&this._clear();return!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){var n=!this.options.handle||!e(this.options.handle,this.element).length?!0:!1;return e(this.options.handle,this.element).find("*").andSelf().each(function(){this==t.target&&(n=!0)}),n},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t])):n.helper=="clone"?this.element.clone().removeAttr("id"):this.element;return r.parents("body").length||r.appendTo(n.appendTo=="parent"?this.element[0].parentNode:n.appendTo),r[0]!=this.element[0]&&!/(fixed|absolute)/.test(r.css("position"))&&r.css("position","absolute"),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.ui.ie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[t.containment=="document"?0:e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t.containment=="document"?0:e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(t.containment=="document"?0:e(window).scrollLeft())+e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(t.containment=="document"?0:e(window).scrollTop())+(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)&&t.containment.constructor!=Array){var n=e(t.containment),r=n[0];if(!r)return;var i=n.offset(),s=e(r).css("overflow")!="hidden";this.containment=[(parseInt(e(r).css("borderLeftWidth"),10)||0)+(parseInt(e(r).css("paddingLeft"),10)||0),(parseInt(e(r).css("borderTopWidth"),10)||0)+(parseInt(e(r).css("paddingTop"),10)||0),(s?Math.max(r.scrollWidth,r.offsetWidth):r.offsetWidth)-(parseInt(e(r).css("borderLeftWidth"),10)||0)-(parseInt(e(r).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(s?Math.max(r.scrollHeight,r.offsetHeight):r.offsetHeight)-(parseInt(e(r).css("borderTopWidth"),10)||0)-(parseInt(e(r).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=n}else t.containment.constructor==Array&&(this.containment=t.containment)},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName),s=t.pageX,o=t.pageY;if(this.originalPosition){var u;if(this.containment){if(this.relative_container){var a=this.relative_container.offset();u=[this.containment[0]+a.left,this.containment[1]+a.top,this.containment[2]+a.left,this.containment[3]+a.top]}else u=this.containment;t.pageX-this.offset.click.left<u[0]&&(s=u[0]+this.offset.click.left),t.pageY-this.offset.click.top<u[1]&&(o=u[1]+this.offset.click.top),t.pageX-this.offset.click.left>u[2]&&(s=u[2]+this.offset.click.left),t.pageY-this.offset.click.top>u[3]&&(o=u[3]+this.offset.click.top)}if(n.grid){var f=n.grid[1]?this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1]:this.originalPageY;o=u?f-this.offset.click.top<u[1]||f-this.offset.click.top>u[3]?f-this.offset.click.top<u[1]?f+n.grid[1]:f-n.grid[1]:f:f;var l=n.grid[0]?this.originalPageX+Math.round((s-this.originalPageX)/n.grid[0])*n.grid[0]:this.originalPageX;s=u?l-this.offset.click.left<u[0]||l-this.offset.click.left>u[2]?l-this.offset.click.left<u[0]?l+n.grid[0]:l-n.grid[0]:l:l}}return{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():i?0:r.scrollTop()),left:s-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:r.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(t,n,r){return r=r||this._uiHash(),e.ui.plugin.call(this,t,[n,r]),t=="drag"&&(this.positionAbs=this._convertPositionTo("absolute")),e.Widget.prototype._trigger.call(this,t,n,r)},plugins:{},_uiHash:function(e){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,n){var r=e(this).data("draggable"),i=r.options,s=e.extend({},n,{item:r.element});r.sortables=[],e(i.connectToSortable).each(function(){var n=e.data(this,"sortable");n&&!n.options.disabled&&(r.sortables.push({instance:n,shouldRevert:n.options.revert}),n.refreshPositions(),n._trigger("activate",t,s))})},stop:function(t,n){var r=e(this).data("draggable"),i=e.extend({},n,{item:r.element});e.each(r.sortables,function(){this.instance.isOver?(this.instance.isOver=0,r.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(t),this.instance.options.helper=this.instance.options._helper,r.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",t,i))})},drag:function(t,n){var r=e(this).data("draggable"),i=this,s=function(t){var n=this.offset.click.top,r=this.offset.click.left,i=this.positionAbs.top,s=this.positionAbs.left,o=t.height,u=t.width,a=t.top,f=t.left;return e.ui.isOver(i+n,s+r,a,f,o,u)};e.each(r.sortables,function(s){var o=!1,u=this;this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(o=!0,e.each(r.sortables,function(){return this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this!=u&&this.instance._intersectsWith(this.instance.containerCache)&&e.ui.contains(u.instance.element[0],this.instance.element[0])&&(o=!1),o})),o?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=e(i).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return n.helper[0]},t.target=this.instance.currentItem[0],this.instance._mouseCapture(t,!0),this.instance._mouseStart(t,!0,!0),this.instance.offset.click.top=r.offset.click.top,this.instance.offset.click.left=r.offset.click.left,this.instance.offset.parent.left-=r.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=r.offset.parent.top-this.instance.offset.parent.top,r._trigger("toSortable",t),r.dropped=this.instance.element,r.currentItem=r.element,this.instance.fromOutside=r),this.instance.currentItem&&this.instance._mouseDrag(t)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",t,this.instance._uiHash(this.instance)),this.instance._mouseStop(t,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),r._trigger("fromSortable",t),r.dropped=!1)})}}),e.ui.plugin.add("draggable","cursor",{start:function(t,n){var r=e("body"),i=e(this).data("draggable").options;r.css("cursor")&&(i._cursor=r.css("cursor")),r.css("cursor",i.cursor)},stop:function(t,n){var r=e(this).data("draggable").options;r._cursor&&e("body").css("cursor",r._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,n){var r=e(n.helper),i=e(this).data("draggable").options;r.css("opacity")&&(i._opacity=r.css("opacity")),r.css("opacity",i.opacity)},stop:function(t,n){var r=e(this).data("draggable").options;r._opacity&&e(n.helper).css("opacity",r._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(t,n){var r=e(this).data("draggable");r.scrollParent[0]!=document&&r.scrollParent[0].tagName!="HTML"&&(r.overflowOffset=r.scrollParent.offset())},drag:function(t,n){var r=e(this).data("draggable"),i=r.options,s=!1;if(r.scrollParent[0]!=document&&r.scrollParent[0].tagName!="HTML"){if(!i.axis||i.axis!="x")r.overflowOffset.top+r.scrollParent[0].offsetHeight-t.pageY<i.scrollSensitivity?r.scrollParent[0].scrollTop=s=r.scrollParent[0].scrollTop+i.scrollSpeed:t.pageY-r.overflowOffset.top<i.scrollSensitivity&&(r.scrollParent[0].scrollTop=s=r.scrollParent[0].scrollTop-i.scrollSpeed);if(!i.axis||i.axis!="y")r.overflowOffset.left+r.scrollParent[0].offsetWidth-t.pageX<i.scrollSensitivity?r.scrollParent[0].scrollLeft=s=r.scrollParent[0].scrollLeft+i.scrollSpeed:t.pageX-r.overflowOffset.left<i.scrollSensitivity&&(r.scrollParent[0].scrollLeft=s=r.scrollParent[0].scrollLeft-i.scrollSpeed)}else{if(!i.axis||i.axis!="x")t.pageY-e(document).scrollTop()<i.scrollSensitivity?s=e(document).scrollTop(e(document).scrollTop()-i.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<i.scrollSensitivity&&(s=e(document).scrollTop(e(document).scrollTop()+i.scrollSpeed));if(!i.axis||i.axis!="y")t.pageX-e(document).scrollLeft()<i.scrollSensitivity?s=e(document).scrollLeft(e(document).scrollLeft()-i.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<i.scrollSensitivity&&(s=e(document).scrollLeft(e(document).scrollLeft()+i.scrollSpeed))}s!==!1&&e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(r,t)}}),e.ui.plugin.add("draggable","snap",{start:function(t,n){var r=e(this).data("draggable"),i=r.options;r.snapElements=[],e(i.snap.constructor!=String?i.snap.items||":data(draggable)":i.snap).each(function(){var t=e(this),n=t.offset();this!=r.element[0]&&r.snapElements.push({item:this,width:t.outerWidth(),height:t.outerHeight(),top:n.top,left:n.left})})},drag:function(t,n){var r=e(this).data("draggable"),i=r.options,s=i.snapTolerance,o=n.offset.left,u=o+r.helperProportions.width,a=n.offset.top,f=a+r.helperProportions.height;for(var l=r.snapElements.length-1;l>=0;l--){var c=r.snapElements[l].left,h=c+r.snapElements[l].width,p=r.snapElements[l].top,d=p+r.snapElements[l].height;if(!(c-s<o&&o<h+s&&p-s<a&&a<d+s||c-s<o&&o<h+s&&p-s<f&&f<d+s||c-s<u&&u<h+s&&p-s<a&&a<d+s||c-s<u&&u<h+s&&p-s<f&&f<d+s)){r.snapElements[l].snapping&&r.options.snap.release&&r.options.snap.release.call(r.element,t,e.extend(r._uiHash(),{snapItem:r.snapElements[l].item})),r.snapElements[l].snapping=!1;continue}if(i.snapMode!="inner"){var v=Math.abs(p-f)<=s,m=Math.abs(d-a)<=s,g=Math.abs(c-u)<=s,y=Math.abs(h-o)<=s;v&&(n.position.top=r._convertPositionTo("relative",{top:p-r.helperProportions.height,left:0}).top-r.margins.top),m&&(n.position.top=r._convertPositionTo("relative",{top:d,left:0}).top-r.margins.top),g&&(n.position.left=r._convertPositionTo("relative",{top:0,left:c-r.helperProportions.width}).left-r.margins.left),y&&(n.position.left=r._convertPositionTo("relative",{top:0,left:h}).left-r.margins.left)}var b=v||m||g||y;if(i.snapMode!="outer"){var v=Math.abs(p-a)<=s,m=Math.abs(d-f)<=s,g=Math.abs(c-o)<=s,y=Math.abs(h-u)<=s;v&&(n.position.top=r._convertPositionTo("relative",{top:p,left:0}).top-r.margins.top),m&&(n.position.top=r._convertPositionTo("relative",{top:d-r.helperProportions.height,left:0}).top-r.margins.top),g&&(n.position.left=r._convertPositionTo("relative",{top:0,left:c}).left-r.margins.left),y&&(n.position.left=r._convertPositionTo("relative",{top:0,left:h-r.helperProportions.width}).left-r.margins.left)}!r.snapElements[l].snapping&&(v||m||g||y||b)&&r.options.snap.snap&&r.options.snap.snap.call(r.element,t,e.extend(r._uiHash(),{snapItem:r.snapElements[l].item})),r.snapElements[l].snapping=v||m||g||y||b}}}),e.ui.plugin.add("draggable","stack",{start:function(t,n){var r=e(this).data("draggable").options,i=e.makeArray(e(r.stack)).sort(function(t,n){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(n).css("zIndex"),10)||0)});if(!i.length)return;var s=parseInt(i[0].style.zIndex)||0;e(i).each(function(e){this.style.zIndex=s+e}),this[0].style.zIndex=s+i.length}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,n){var r=e(n.helper),i=e(this).data("draggable").options;r.css("zIndex")&&(i._zIndex=r.css("zIndex")),r.css("zIndex",i.zIndex)},stop:function(t,n){var r=e(this).data("draggable").options;r._zIndex&&e(n.helper).css("zIndex",r._zIndex)}})})(jQuery);(function(e,t){e.widget("ui.droppable",{version:"1.9.2",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect"},_create:function(){var t=this.options,n=t.accept;this.isover=0,this.isout=1,this.accept=e.isFunction(n)?n:function(e){return e.is(n)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},e.ui.ddmanager.droppables[t.scope]=e.ui.ddmanager.droppables[t.scope]||[],e.ui.ddmanager.droppables[t.scope].push(this),t.addClasses&&this.element.addClass("ui-droppable")},_destroy:function(){var t=e.ui.ddmanager.droppables[this.options.scope];for(var n=0;n<t.length;n++)t[n]==this&&t.splice(n,1);this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(t,n){t=="accept"&&(this.accept=e.isFunction(n)?n:function(e){return e.is(n)}),e.Widget.prototype._setOption.apply(this,arguments)},_activate:function(t){var n=e.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),n&&this._trigger("activate",t,this.ui(n))},_deactivate:function(t){var n=e.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),n&&this._trigger("deactivate",t,this.ui(n))},_over:function(t){var n=e.ui.ddmanager.current;if(!n||(n.currentItem||n.element)[0]==this.element[0])return;this.accept.call(this.element[0],n.currentItem||n.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",t,this.ui(n)))},_out:function(t){var n=e.ui.ddmanager.current;if(!n||(n.currentItem||n.element)[0]==this.element[0])return;this.accept.call(this.element[0],n.currentItem||n.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",t,this.ui(n)))},_drop:function(t,n){var r=n||e.ui.ddmanager.current;if(!r||(r.currentItem||r.element)[0]==this.element[0])return!1;var i=!1;return this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var t=e.data(this,"droppable");if(t.options.greedy&&!t.options.disabled&&t.options.scope==r.options.scope&&t.accept.call(t.element[0],r.currentItem||r.element)&&e.ui.intersect(r,e.extend(t,{offset:t.element.offset()}),t.options.tolerance))return i=!0,!1}),i?!1:this.accept.call(this.element[0],r.currentItem||r.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",t,this.ui(r)),this.element):!1},ui:function(e){return{draggable:e.currentItem||e.element,helper:e.helper,position:e.position,offset:e.positionAbs}}}),e.ui.intersect=function(t,n,r){if(!n.offset)return!1;var i=(t.positionAbs||t.position.absolute).left,s=i+t.helperProportions.width,o=(t.positionAbs||t.position.absolute).top,u=o+t.helperProportions.height,a=n.offset.left,f=a+n.proportions.width,l=n.offset.top,c=l+n.proportions.height;switch(r){case"fit":return a<=i&&s<=f&&l<=o&&u<=c;case"intersect":return a<i+t.helperProportions.width/2&&s-t.helperProportions.width/2<f&&l<o+t.helperProportions.height/2&&u-t.helperProportions.height/2<c;case"pointer":var h=(t.positionAbs||t.position.absolute).left+(t.clickOffset||t.offset.click).left,p=(t.positionAbs||t.position.absolute).top+(t.clickOffset||t.offset.click).top,d=e.ui.isOver(p,h,l,a,n.proportions.height,n.proportions.width);return d;case"touch":return(o>=l&&o<=c||u>=l&&u<=c||o<l&&u>c)&&(i>=a&&i<=f||s>=a&&s<=f||i<a&&s>f);default:return!1}},e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,n){var r=e.ui.ddmanager.droppables[t.options.scope]||[],i=n?n.type:null,s=(t.currentItem||t.element).find(":data(droppable)").andSelf();e:for(var o=0;o<r.length;o++){if(r[o].options.disabled||t&&!r[o].accept.call(r[o].element[0],t.currentItem||t.element))continue;for(var u=0;u<s.length;u++)if(s[u]==r[o].element[0]){r[o].proportions.height=0;continue e}r[o].visible=r[o].element.css("display")!="none";if(!r[o].visible)continue;i=="mousedown"&&r[o]._activate.call(r[o],n),r[o].offset=r[o].element.offset(),r[o].proportions={width:r[o].element[0].offsetWidth,height:r[o].element[0].offsetHeight}}},drop:function(t,n){var r=!1;return e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(!this.options)return;!this.options.disabled&&this.visible&&e.ui.intersect(t,this,this.options.tolerance)&&(r=this._drop.call(this,n)||r),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=1,this.isover=0,this._deactivate.call(this,n))}),r},dragStart:function(t,n){t.element.parentsUntil("body").bind("scroll.droppable",function(){t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,n)})},drag:function(t,n){t.options.refreshPositions&&e.ui.ddmanager.prepareOffsets(t,n),e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(this.options.disabled||this.greedyChild||!this.visible)return;var r=e.ui.intersect(t,this,this.options.tolerance),i=!r&&this.isover==1?"isout":r&&this.isover==0?"isover":null;if(!i)return;var s;if(this.options.greedy){var o=this.options.scope,u=this.element.parents(":data(droppable)").filter(function(){return e.data(this,"droppable").options.scope===o});u.length&&(s=e.data(u[0],"droppable"),s.greedyChild=i=="isover"?1:0)}s&&i=="isover"&&(s.isover=0,s.isout=1,s._out.call(s,n)),this[i]=1,this[i=="isout"?"isover":"isout"]=0,this[i=="isover"?"_over":"_out"].call(this,n),s&&i=="isout"&&(s.isout=0,s.isover=1,s._over.call(s,n))})},dragStop:function(t,n){t.element.parentsUntil("body").unbind("scroll.droppable"),t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,n)}}})(jQuery);(function(e,t){e.widget("ui.selectable",e.ui.mouse,{version:"1.9.2",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var t=this;this.element.addClass("ui-selectable"),this.dragged=!1;var n;this.refresh=function(){n=e(t.options.filter,t.element[0]),n.addClass("ui-selectee"),n.each(function(){var t=e(this),n=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:n.left,top:n.top,right:n.left+t.outerWidth(),bottom:n.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=n.addClass("ui-selectee"),this._mouseInit(),this.helper=e("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var n=this;this.opos=[t.pageX,t.pageY];if(this.options.disabled)return;var r=this.options;this.selectees=e(r.filter,this.element[0]),this._trigger("start",t),e(r.appendTo).append(this.helper),this.helper.css({left:t.clientX,top:t.clientY,width:0,height:0}),r.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var r=e.data(this,"selectable-item");r.startselected=!0,!t.metaKey&&!t.ctrlKey&&(r.$element.removeClass("ui-selected"),r.selected=!1,r.$element.addClass("ui-unselecting"),r.unselecting=!0,n._trigger("unselecting",t,{unselecting:r.element}))}),e(t.target).parents().andSelf().each(function(){var r=e.data(this,"selectable-item");if(r){var i=!t.metaKey&&!t.ctrlKey||!r.$element.hasClass("ui-selected");return r.$element.removeClass(i?"ui-unselecting":"ui-selected").addClass(i?"ui-selecting":"ui-unselecting"),r.unselecting=!i,r.selecting=i,r.selected=i,i?n._trigger("selecting",t,{selecting:r.element}):n._trigger("unselecting",t,{unselecting:r.element}),!1}})},_mouseDrag:function(t){var n=this;this.dragged=!0;if(this.options.disabled)return;var r=this.options,i=this.opos[0],s=this.opos[1],o=t.pageX,u=t.pageY;if(i>o){var a=o;o=i,i=a}if(s>u){var a=u;u=s,s=a}return this.helper.css({left:i,top:s,width:o-i,height:u-s}),this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!a||a.element==n.element[0])return;var f=!1;r.tolerance=="touch"?f=!(a.left>o||a.right<i||a.top>u||a.bottom<s):r.tolerance=="fit"&&(f=a.left>i&&a.right<o&&a.top>s&&a.bottom<u),f?(a.selected&&(a.$element.removeClass("ui-selected"),a.selected=!1),a.unselecting&&(a.$element.removeClass("ui-unselecting"),a.unselecting=!1),a.selecting||(a.$element.addClass("ui-selecting"),a.selecting=!0,n._trigger("selecting",t,{selecting:a.element}))):(a.selecting&&((t.metaKey||t.ctrlKey)&&a.startselected?(a.$element.removeClass("ui-selecting"),a.selecting=!1,a.$element.addClass("ui-selected"),a.selected=!0):(a.$element.removeClass("ui-selecting"),a.selecting=!1,a.startselected&&(a.$element.addClass("ui-unselecting"),a.unselecting=!0),n._trigger("unselecting",t,{unselecting:a.element}))),a.selected&&!t.metaKey&&!t.ctrlKey&&!a.startselected&&(a.$element.removeClass("ui-selected"),a.selected=!1,a.$element.addClass("ui-unselecting"),a.unselecting=!0,n._trigger("unselecting",t,{unselecting:a.element})))}),!1},_mouseStop:function(t){var n=this;this.dragged=!1;var r=this.options;return e(".ui-unselecting",this.element[0]).each(function(){var r=e.data(this,"selectable-item");r.$element.removeClass("ui-unselecting"),r.unselecting=!1,r.startselected=!1,n._trigger("unselected",t,{unselected:r.element})}),e(".ui-selecting",this.element[0]).each(function(){var r=e.data(this,"selectable-item");r.$element.removeClass("ui-selecting").addClass("ui-selected"),r.selecting=!1,r.selected=!0,r.startselected=!0,n._trigger("selected",t,{selected:r.element})}),this._trigger("stop",t),this.helper.remove(),!1}})})(jQuery);(function(e,t){e.widget("ui.sortable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?e.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,n){t==="disabled"?(this.options[t]=n,this.widget().toggleClass("ui-sortable-disabled",!!n)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,n){var r=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(t);var i=null,s=e(t.target).parents().each(function(){if(e.data(this,r.widgetName+"-item")==r)return i=e(this),!1});e.data(t.target,r.widgetName+"-item")==r&&(i=e(t.target));if(!i)return!1;if(this.options.handle&&!n){var o=!1;e(this.options.handle,i).find("*").andSelf().each(function(){this==t.target&&(o=!0)});if(!o)return!1}return this.currentItem=i,this._removeCurrentsFromItems(),!0},_mouseStart:function(t,n,r){var i=this.options;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),i.containment&&this._setContainment(),i.cursor&&(e("body").css("cursor")&&(this._storedCursor=e("body").css("cursor")),e("body").css("cursor",i.cursor)),i.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",i.opacity)),i.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",i.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!r)for(var s=this.containers.length-1;s>=0;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var n=this.options,r=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<n.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+n.scrollSpeed:t.pageY-this.overflowOffset.top<n.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-n.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<n.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+n.scrollSpeed:t.pageX-this.overflowOffset.left<n.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-n.scrollSpeed)):(t.pageY-e(document).scrollTop()<n.scrollSensitivity?r=e(document).scrollTop(e(document).scrollTop()-n.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<n.scrollSensitivity&&(r=e(document).scrollTop(e(document).scrollTop()+n.scrollSpeed)),t.pageX-e(document).scrollLeft()<n.scrollSensitivity?r=e(document).scrollLeft(e(document).scrollLeft()-n.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<n.scrollSensitivity&&(r=e(document).scrollLeft(e(document).scrollLeft()+n.scrollSpeed))),r!==!1&&e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(var i=this.items.length-1;i>=0;i--){var s=this.items[i],o=s.item[0],u=this._intersectsWithPointer(s);if(!u)continue;if(s.instance!==this.currentContainer)continue;if(o!=this.currentItem[0]&&this.placeholder[u==1?"next":"prev"]()[0]!=o&&!e.contains(this.placeholder[0],o)&&(this.options.type=="semi-dynamic"?!e.contains(this.element[0],o):!0)){this.direction=u==1?"down":"up";if(this.options.tolerance!="pointer"&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,n){if(!t)return;e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t);if(this.options.revert){var r=this,i=this.placeholder.offset();this.reverting=!0,e(this.helper).animate({left:i.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:i.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){r._clear(t)})}else this._clear(t,n);return!1},cancel:function(){if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},e(n).each(function(){var n=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[-=_](.+)/);n&&r.push((t.key||n[1]+"[]")+"="+(t.key&&t.expression?n[1]:n[2]))}),!r.length&&t.key&&r.push(t.key+"="),r.join("&")},toArray:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},n.each(function(){r.push(e(t.item||this).attr(t.attribute||"id")||"")}),r},_intersectsWith:function(e){var t=this.positionAbs.left,n=t+this.helperProportions.width,r=this.positionAbs.top,i=r+this.helperProportions.height,s=e.left,o=s+e.width,u=e.top,a=u+e.height,f=this.offset.click.top,l=this.offset.click.left,c=r+f>u&&r+f<a&&t+l>s&&t+l<o;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?c:s<t+this.helperProportions.width/2&&n-this.helperProportions.width/2<o&&u<r+this.helperProportions.height/2&&i-this.helperProportions.height/2<a},_intersectsWithPointer:function(t){var n=this.options.axis==="x"||e.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),r=this.options.axis==="y"||e.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),i=n&&r,s=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return i?this.floating?o&&o=="right"||s=="down"?2:1:s&&(s=="down"?2:1):!1},_intersectsWithSides:function(t){var n=e.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),r=e.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),i=this._getDragVerticalDirection(),s=this._getDragHorizontalDirection();return this.floating&&s?s=="right"&&r||s=="left"&&!r:i&&(i=="down"&&n||i=="up"&&!n)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return e!=0&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return e!=0&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor==String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){var n=[],r=[],i=this._connectWith();if(i&&t)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&r.push([e.isFunction(a.options.items)?a.options.items.call(a.element):e(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a])}}r.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var s=r.length-1;s>=0;s--)r[s][0].each(function(){n.push(this)});return e(n)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var n=0;n<t.length;n++)if(t[n]==e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var n=this.items,r=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],i=this._connectWith();if(i&&this.ready)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&(r.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a))}}for(var s=r.length-1;s>=0;s--){var f=r[s][1],l=r[s][0];for(var u=0,c=l.length;u<c;u++){var h=e(l[u]);h.data(this.widgetName+"-item",f),n.push({item:h,instance:f,width:0,height:0,left:0,top:0})}}},refreshPositions:function(t){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());for(var n=this.items.length-1;n>=0;n--){var r=this.items[n];if(r.instance!=this.currentContainer&&this.currentContainer&&r.item[0]!=this.currentItem[0])continue;var i=this.options.toleranceElement?e(this.options.toleranceElement,r.item):r.item;t||(r.width=i.outerWidth(),r.height=i.outerHeight());var s=i.offset();r.left=s.left,r.top=s.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var n=this.containers.length-1;n>=0;n--){var s=this.containers[n].element.offset();this.containers[n].containerCache.left=s.left,this.containers[n].containerCache.top=s.top,this.containers[n].containerCache.width=this.containers[n].element.outerWidth(),this.containers[n].containerCache.height=this.containers[n].element.outerHeight()}return this},_createPlaceholder:function(t){t=t||this;var n=t.options;if(!n.placeholder||n.placeholder.constructor==String){var r=n.placeholder;n.placeholder={element:function(){var n=e(document.createElement(t.currentItem[0].nodeName)).addClass(r||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return r||(n.style.visibility="hidden"),n},update:function(e,i){if(r&&!n.forcePlaceholderSize)return;i.height()||i.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),i.width()||i.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10))}}}t.placeholder=e(n.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),n.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var n=null,r=null;for(var i=this.containers.length-1;i>=0;i--){if(e.contains(this.currentItem[0],this.containers[i].element[0]))continue;if(this._intersectsWith(this.containers[i].containerCache)){if(n&&e.contains(this.containers[i].element[0],n.element[0]))continue;n=this.containers[i],r=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0)}if(!n)return;if(this.containers.length===1)this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1;else{var s=1e4,o=null,u=this.containers[r].floating?"left":"top",a=this.containers[r].floating?"width":"height",f=this.positionAbs[u]+this.offset.click[u];for(var l=this.items.length-1;l>=0;l--){if(!e.contains(this.containers[r].element[0],this.items[l].item[0]))continue;if(this.items[l].item[0]==this.currentItem[0])continue;var c=this.items[l].item.offset()[u],h=!1;Math.abs(c-f)>Math.abs(c+this.items[l][a]-f)&&(h=!0,c+=this.items[l][a]),Math.abs(c-f)<s&&(s=Math.abs(c-f),o=this.items[l],this.direction=h?"up":"down")}if(!o&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[r],o?this._rearrange(t,o,null,!0):this._rearrange(t,null,this.containers[r].element,!0),this._trigger("change",t,this._uiHash()),this.containers[r]._trigger("change",t,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1}},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t,this.currentItem])):n.helper=="clone"?this.currentItem.clone():this.currentItem;return r.parents("body").length||e(n.appendTo!="parent"?n.appendTo:this.currentItem[0].parentNode)[0].appendChild(r[0]),r[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(r[0].style.width==""||n.forceHelperSize)&&r.width(this.currentItem.width()),(r[0].style.height==""||n.forceHelperSize)&&r.height(this.currentItem.height()),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.ui.ie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)){var n=e(t.containment)[0],r=e(t.containment).offset(),i=e(n).css("overflow")!="hidden";this.containment=[r.left+(parseInt(e(n).css("borderLeftWidth"),10)||0)+(parseInt(e(n).css("paddingLeft"),10)||0)-this.margins.left,r.top+(parseInt(e(n).css("borderTopWidth"),10)||0)+(parseInt(e(n).css("paddingTop"),10)||0)-this.margins.top,r.left+(i?Math.max(n.scrollWidth,n.offsetWidth):n.offsetWidth)-(parseInt(e(n).css("borderLeftWidth"),10)||0)-(parseInt(e(n).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,r.top+(i?Math.max(n.scrollHeight,n.offsetHeight):n.offsetHeight)-(parseInt(e(n).css("borderTopWidth"),10)||0)-(parseInt(e(n).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var s=t.pageX,o=t.pageY;if(this.originalPosition){this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(s=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(o=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(s=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top));if(n.grid){var u=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1];o=this.containment?u-this.offset.click.top<this.containment[1]||u-this.offset.click.top>this.containment[3]?u-this.offset.click.top<this.containment[1]?u+n.grid[1]:u-n.grid[1]:u:u;var a=this.originalPageX+Math.round((s-this.originalPageX)/n.grid[0])*n.grid[0];s=this.containment?a-this.offset.click.left<this.containment[0]||a-this.offset.click.left>this.containment[2]?a-this.offset.click.left<this.containment[0]?a+n.grid[0]:a-n.grid[0]:a:a}}return{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():i?0:r.scrollTop()),left:s-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:r.scrollLeft())}},_rearrange:function(e,t,n,r){n?n[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var i=this.counter;this._delay(function(){i==this.counter&&this.refreshPositions(!r)})},_clear:function(t,n){this.reverting=!1;var r=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var i in this._storedCSS)if(this._storedCSS[i]=="auto"||this._storedCSS[i]=="static")this._storedCSS[i]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!n&&r.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!n&&r.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(n||(r.push(function(e){this._trigger("remove",e,this._uiHash())}),r.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),r.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer))));for(var i=this.containers.length-1;i>=0;i--)n||r.push(function(e){return function(t){e._trigger("deactivate",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(r.push(function(e){return function(t){e._trigger("out",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);this._storedCursor&&e("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!n){this._trigger("beforeStop",t,this._uiHash());for(var i=0;i<r.length;i++)r[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}n||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!=this.currentItem[0]&&this.helper.remove(),this.helper=null;if(!n){for(var i=0;i<r.length;i++)r[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var n=t||this;return{helper:n.helper,placeholder:n.placeholder||e([]),position:n.position,originalPosition:n.originalPosition,offset:n.positionAbs,item:n.currentItem,sender:t?t.element:null}}})})(jQuery); \ No newline at end of file
diff --git a/horizon/static/horizon/lib/jquery/jquery.cookie.js b/horizon/static/horizon/lib/jquery/jquery.cookie.js
deleted file mode 100644
index 6d5974a2..00000000
--- a/horizon/static/horizon/lib/jquery/jquery.cookie.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*!
- * jQuery Cookie Plugin
- * https://github.com/carhartl/jquery-cookie
- *
- * Copyright 2011, Klaus Hartl
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.opensource.org/licenses/GPL-2.0
- */
-(function($) {
- $.cookie = function(key, value, options) {
-
- // key and at least value given, set cookie...
- if (arguments.length > 1 && (!/Object/.test(Object.prototype.toString.call(value)) || value === null || value === undefined)) {
- options = $.extend({}, options);
-
- if (value === null || value === undefined) {
- options.expires = -1;
- }
-
- if (typeof options.expires === 'number') {
- var days = options.expires, t = options.expires = new Date();
- t.setDate(t.getDate() + days);
- }
-
- value = String(value);
-
- return (document.cookie = [
- encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(value),
- options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
- options.path ? '; path=' + options.path : '',
- options.domain ? '; domain=' + options.domain : '',
- options.secure ? '; secure' : ''
- ].join(''));
- }
-
- // key and possibly options given, get cookie...
- options = value || {};
- var decode = options.raw ? function(s) { return s; } : decodeURIComponent;
-
- var pairs = document.cookie.split('; ');
- for (var i = 0, pair; pair = pairs[i] && pairs[i].split('='); i++) {
- if (decode(pair[0]) === key) return decode(pair[1] || ''); // IE saves cookies with empty string as "c; ", e.g. without "=" as opposed to EOMB, thus pair[1] may be undefined
- }
- return null;
- };
-})(jQuery);
diff --git a/horizon/static/horizon/lib/jquery/jquery.min.js b/horizon/static/horizon/lib/jquery/jquery.min.js
deleted file mode 100644
index b1b47b81..00000000
--- a/horizon/static/horizon/lib/jquery/jquery.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery v1.7.1 jquery.com | jquery.org/license */
-(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
-f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
-{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
diff --git a/horizon/static/horizon/lib/jquery/jquery.quicksearch.js b/horizon/static/horizon/lib/jquery/jquery.quicksearch.js
deleted file mode 100644
index 7bd6f65a..00000000
--- a/horizon/static/horizon/lib/jquery/jquery.quicksearch.js
+++ /dev/null
@@ -1,150 +0,0 @@
-(function($, window, document, undefined) {
- $.fn.quicksearch = function (target, opt) {
-
- var timeout, cache, rowcache, jq_results, val = '', e = this, options = $.extend({
- delay: 100,
- selector: null,
- stripeRows: null,
- loader: null,
- noResults: '',
- bind: 'keyup',
- onBefore: function () {
- return;
- },
- onAfter: function () {
- return;
- },
- show: function () {
- this.style.display = "";
- },
- hide: function () {
- this.style.display = "none";
- },
- prepareQuery: function (val) {
- return val.toLowerCase().split(' ');
- },
- testQuery: function (query, txt, _row) {
- for (var i = 0; i < query.length; i += 1) {
- if (txt.indexOf(query[i]) === -1) {
- return false;
- }
- }
- return true;
- }
- }, opt);
-
- this.go = function () {
-
- var i = 0,
- noresults = true,
- query = options.prepareQuery(val),
- val_empty = (val.replace(' ', '').length === 0);
-
- for (var i = 0, len = rowcache.length; i < len; i++) {
- if (val_empty || options.testQuery(query, cache[i], rowcache[i])) {
- options.show.apply(rowcache[i]);
- noresults = false;
- } else {
- options.hide.apply(rowcache[i]);
- }
- }
-
- if (noresults) {
- this.results(false);
- } else {
- this.results(true);
- this.stripe();
- }
-
- this.loader(false);
- options.onAfter();
-
- return this;
- };
-
- this.stripe = function () {
-
- if (typeof options.stripeRows === "object" && options.stripeRows !== null)
- {
- var joined = options.stripeRows.join(' ');
- var stripeRows_length = options.stripeRows.length;
-
- jq_results.not(':hidden').each(function (i) {
- $(this).removeClass(joined).addClass(options.stripeRows[i % stripeRows_length]);
- });
- }
-
- return this;
- };
-
- this.strip_html = function (input) {
- var output = input.replace(new RegExp('<[^<]+\>', 'g'), "");
- output = $.trim(output.toLowerCase());
- return output;
- };
-
- this.results = function (bool) {
- if (typeof options.noResults === "string" && options.noResults !== "") {
- if (bool) {
- $(options.noResults).hide();
- } else {
- $(options.noResults).show();
- }
- }
- return this;
- };
-
- this.loader = function (bool) {
- if (typeof options.loader === "string" && options.loader !== "") {
- (bool) ? $(options.loader).show() : $(options.loader).hide();
- }
- return this;
- };
-
- this.cache = function () {
-
- jq_results = $(target);
-
- if (typeof options.noResults === "string" && options.noResults !== "") {
- jq_results = jq_results.not(options.noResults);
- }
-
- var t = (typeof options.selector === "string") ? jq_results.find(options.selector) : $(target).not(options.noResults);
- cache = t.map(function () {
- return e.strip_html(this.innerHTML);
- });
-
- rowcache = jq_results.map(function () {
- return this;
- });
-
- return this.go();
- };
-
- this.trigger = function () {
- this.loader(true);
- options.onBefore();
-
- window.clearTimeout(timeout);
- timeout = window.setTimeout(function () {
- e.go();
- }, options.delay);
-
- return this;
- };
-
- this.cache();
- this.results(true);
- this.stripe();
- this.loader(false);
-
- return this.each(function () {
- $(this).bind(options.bind, function () {
- val = $(this).val();
- e.trigger();
- });
- });
-
- };
-
-}(jQuery, this, document)); \ No newline at end of file
diff --git a/horizon/static/horizon/lib/jquery/jquery.table-sorter.js b/horizon/static/horizon/lib/jquery/jquery.table-sorter.js
deleted file mode 100644
index c4eb1cbd..00000000
--- a/horizon/static/horizon/lib/jquery/jquery.table-sorter.js
+++ /dev/null
@@ -1,1031 +0,0 @@
-/*
- *
- * TableSorter 2.0 - Client-side table sorting with ease!
- * Version 2.0.5b
- * @requires jQuery v1.2.3
- *
- * Copyright (c) 2007 Christian Bach
- * Examples and docs at: http://tablesorter.com
- * Dual licensed under the MIT and GPL licenses:
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- */
-/**
- *
- * @description Create a sortable table with multi-column sorting capabilitys
- *
- * @example $('table').tablesorter();
- * @desc Create a simple tablesorter interface.
- *
- * @example $('table').tablesorter({ sortList:[[0,0],[1,0]] });
- * @desc Create a tablesorter interface and sort on the first and secound column column headers.
- *
- * @example $('table').tablesorter({ headers: { 0: { sorter: false}, 1: {sorter: false} } });
- *
- * @desc Create a tablesorter interface and disableing the first and second column headers.
- *
- *
- * @example $('table').tablesorter({ headers: { 0: {sorter:"integer"}, 1: {sorter:"currency"} } });
- *
- * @desc Create a tablesorter interface and set a column parser for the first
- * and second column.
- *
- *
- * @param Object
- * settings An object literal containing key/value pairs to provide
- * optional settings.
- *
- *
- * @option String cssHeader (optional) A string of the class name to be appended
- * to sortable tr elements in the thead of the table. Default value:
- * "header"
- *
- * @option String cssAsc (optional) A string of the class name to be appended to
- * sortable tr elements in the thead on an ascending sort. Default value:
- * "headerSortUp"
- *
- * @option String cssDesc (optional) A string of the class name to be appended
- * to sortable tr elements in the thead on a descending sort. Default
- * value: "headerSortDown"
- *
- * @option String sortInitialOrder (optional) A string of the inital sorting
- * order can be asc or desc. Default value: "asc"
- *
- * @option String sortMultisortKey (optional) A string of the multi-column sort
- * key. Default value: "shiftKey"
- *
- * @option String textExtraction (optional) A string of the text-extraction
- * method to use. For complex html structures inside td cell set this
- * option to "complex", on large tables the complex option can be slow.
- * Default value: "simple"
- *
- * @option Object headers (optional) An array containing the forces sorting
- * rules. This option let's you specify a default sorting rule. Default
- * value: null
- *
- * @option Array sortList (optional) An array containing the forces sorting
- * rules. This option let's you specify a default sorting rule. Default
- * value: null
- *
- * @option Array sortForce (optional) An array containing forced sorting rules.
- * This option let's you specify a default sorting rule, which is
- * prepended to user-selected rules. Default value: null
- *
- * @option Boolean sortLocaleCompare (optional) Boolean flag indicating whatever
- * to use String.localeCampare method or not. Default set to true.
- *
- *
- * @option Array sortAppend (optional) An array containing forced sorting rules.
- * This option let's you specify a default sorting rule, which is
- * appended to user-selected rules. Default value: null
- *
- * @option Boolean widthFixed (optional) Boolean flag indicating if tablesorter
- * should apply fixed widths to the table columns. This is usefull when
- * using the pager companion plugin. This options requires the dimension
- * jquery plugin. Default value: false
- *
- * @option Boolean cancelSelection (optional) Boolean flag indicating if
- * tablesorter should cancel selection of the table headers text.
- * Default value: true
- *
- * @option Boolean debug (optional) Boolean flag indicating if tablesorter
- * should display debuging information usefull for development.
- *
- * @type jQuery
- *
- * @name tablesorter
- *
- * @cat Plugins/Tablesorter
- *
- * @author Christian Bach/christian.bach@polyester.se
- */
-
-(function ($) {
- $.extend({
- tablesorter: new
- function () {
-
- var parsers = [],
- widgets = [];
-
- this.defaults = {
- cssHeader: "header",
- cssAsc: "headerSortUp",
- cssDesc: "headerSortDown",
- cssChildRow: "expand-child",
- sortInitialOrder: "asc",
- sortMultiSortKey: "shiftKey",
- sortForce: null,
- sortAppend: null,
- sortLocaleCompare: true,
- textExtraction: "simple",
- parsers: {}, widgets: [],
- widgetZebra: {
- css: ["even", "odd"]
- }, headers: {}, widthFixed: false,
- cancelSelection: true,
- sortList: [],
- headerList: [],
- dateFormat: "us",
- decimal: '/\.|\,/g',
- onRenderHeader: null,
- selectorHeaders: 'thead th',
- debug: false
- };
-
- /* debuging utils */
-
- function benchmark(s, d) {
- log(s + "," + (new Date().getTime() - d.getTime()) + "ms");
- }
-
- this.benchmark = benchmark;
-
- function log(s) {
- if (typeof console != "undefined" && typeof console.debug != "undefined") {
- console.log(s);
- } else {
- alert(s);
- }
- }
-
- /* parsers utils */
-
- function buildParserCache(table, $headers) {
-
- if (table.config.debug) {
- var parsersDebug = "";
- }
-
- if (table.tBodies.length == 0) return; // In the case of empty tables
- var rows = table.tBodies[0].rows;
-
- if (rows[0]) {
-
- var list = [],
- cells = rows[0].cells,
- l = cells.length;
-
- for (var i = 0; i < l; i++) {
-
- var p = false;
-
- if ($.metadata && ($($headers[i]).metadata() && $($headers[i]).metadata().sorter)) {
-
- p = getParserById($($headers[i]).metadata().sorter);
-
- } else if ((table.config.headers[i] && table.config.headers[i].sorter)) {
-
- p = getParserById(table.config.headers[i].sorter);
- }
- if (!p) {
-
- p = detectParserForColumn(table, rows, -1, i);
- }
-
- if (table.config.debug) {
- parsersDebug += "column:" + i + " parser:" + p.id + "\n";
- }
-
- list.push(p);
- }
- }
-
- if (table.config.debug) {
- log(parsersDebug);
- }
-
- return list;
- };
-
- function detectParserForColumn(table, rows, rowIndex, cellIndex) {
- var l = parsers.length,
- node = false,
- nodeValue = false,
- keepLooking = true;
- while (nodeValue == '' && keepLooking) {
- rowIndex++;
- if (rows[rowIndex]) {
- node = getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex);
- nodeValue = trimAndGetNodeText(table.config, node);
- if (table.config.debug) {
- log('Checking if value was empty on row:' + rowIndex);
- }
- } else {
- keepLooking = false;
- }
- }
- for (var i = 1; i < l; i++) {
- if (parsers[i].is(nodeValue, table, node)) {
- return parsers[i];
- }
- }
- // 0 is always the generic parser (text)
- return parsers[0];
- }
-
- function getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex) {
- return rows[rowIndex].cells[cellIndex];
- }
-
- function trimAndGetNodeText(config, node) {
- return $.trim(getElementText(config, node));
- }
-
- function getParserById(name) {
- var l = parsers.length;
- for (var i = 0; i < l; i++) {
- if (parsers[i].id.toLowerCase() == name.toLowerCase()) {
- return parsers[i];
- }
- }
- return false;
- }
-
- /* utils */
-
- function buildCache(table) {
-
- if (table.config.debug) {
- var cacheTime = new Date();
- }
-
- var totalRows = (table.tBodies[0] && table.tBodies[0].rows.length) || 0,
- totalCells = (table.tBodies[0].rows[0] && table.tBodies[0].rows[0].cells.length) || 0,
- parsers = table.config.parsers,
- cache = {
- row: [],
- normalized: []
- };
-
- for (var i = 0; i < totalRows; ++i) {
-
- /** Add the table data to main data array */
- var c = $(table.tBodies[0].rows[i]),
- cols = [];
-
- // if this is a child row, add it to the last row's children and
- // continue to the next row
- if (c.hasClass(table.config.cssChildRow)) {
- cache.row[cache.row.length - 1] = cache.row[cache.row.length - 1].add(c);
- // go to the next for loop
- continue;
- }
-
- cache.row.push(c);
-
- for (var j = 0; j < totalCells; ++j) {
- cols.push(parsers[j].format(getElementText(table.config, c[0].cells[j]), table, c[0].cells[j]));
- }
-
- cols.push(cache.normalized.length); // add position for rowCache
- cache.normalized.push(cols);
- cols = null;
- };
-
- if (table.config.debug) {
- benchmark("Building cache for " + totalRows + " rows:", cacheTime);
- }
-
- return cache;
- };
-
- function getElementText(config, node) {
-
- var text = "";
-
- if (!node) return "";
-
- if (!config.supportsTextContent) config.supportsTextContent = node.textContent || false;
-
- if (config.textExtraction == "simple") {
- if (config.supportsTextContent) {
- text = node.textContent;
- } else {
- if (node.childNodes[0] && node.childNodes[0].hasChildNodes()) {
- text = node.childNodes[0].innerHTML;
- } else {
- text = node.innerHTML;
- }
- }
- } else {
- if (typeof(config.textExtraction) == "function") {
- text = config.textExtraction(node);
- } else {
- text = $(node).text();
- }
- }
- return text;
- }
-
- function appendToTable(table, cache) {
-
- if (table.config.debug) {
- var appendTime = new Date()
- }
-
- var c = cache,
- r = c.row,
- n = c.normalized,
- totalRows = n.length,
- checkCell = (n[0].length - 1),
- tableBody = $(table.tBodies[0]),
- rows = [];
-
-
- for (var i = 0; i < totalRows; i++) {
- var pos = n[i][checkCell];
-
- rows.push(r[pos]);
-
- if (!table.config.appender) {
-
- //var o = ;
- var l = r[pos].length;
- for (var j = 0; j < l; j++) {
- tableBody[0].appendChild(r[pos][j]);
- }
-
- //
- }
- }
-
-
-
- if (table.config.appender) {
-
- table.config.appender(table, rows);
- }
-
- rows = null;
-
- if (table.config.debug) {
- benchmark("Rebuilt table:", appendTime);
- }
-
- // apply table widgets
- applyWidget(table);
-
- // trigger sortend
- setTimeout(function () {
- $(table).trigger("sortEnd");
- }, 0);
-
- };
-
- function buildHeaders(table) {
-
- if (table.config.debug) {
- var time = new Date();
- }
-
- var meta = ($.metadata) ? true : false;
-
- var header_index = computeTableHeaderCellIndexes(table);
-
- $tableHeaders = $(table.config.selectorHeaders, table).each(function (index) {
-
- this.column = header_index[this.parentNode.rowIndex + "-" + this.cellIndex];
- // this.column = index;
- this.order = formatSortingOrder(table.config.sortInitialOrder);
-
-
- this.count = this.order;
-
- if (checkHeaderMetadata(this) || checkHeaderOptions(table, index)) this.sortDisabled = true;
- if (checkHeaderOptionsSortingLocked(table, index)) this.order = this.lockedOrder = checkHeaderOptionsSortingLocked(table, index);
-
- if (!this.sortDisabled) {
- var $th = $(this).addClass(table.config.cssHeader);
- if (table.config.onRenderHeader) table.config.onRenderHeader.apply($th);
- }
-
- // add cell to headerList
- table.config.headerList[index] = this;
- });
-
- if (table.config.debug) {
- benchmark("Built headers:", time);
- log($tableHeaders);
- }
-
- return $tableHeaders;
-
- };
-
- // from:
- // http://www.javascripttoolbox.com/lib/table/examples.php
- // http://www.javascripttoolbox.com/temp/table_cellindex.html
-
-
- function computeTableHeaderCellIndexes(t) {
- var matrix = [];
- var lookup = {};
- var thead = t.getElementsByTagName('THEAD')[0];
- var trs = thead.getElementsByTagName('TR');
-
- for (var i = 0; i < trs.length; i++) {
- var cells = trs[i].cells;
- for (var j = 0; j < cells.length; j++) {
- var c = cells[j];
-
- var rowIndex = c.parentNode.rowIndex;
- var cellId = rowIndex + "-" + c.cellIndex;
- var rowSpan = c.rowSpan || 1;
- var colSpan = c.colSpan || 1
- var firstAvailCol;
- if (typeof(matrix[rowIndex]) == "undefined") {
- matrix[rowIndex] = [];
- }
- // Find first available column in the first row
- for (var k = 0; k < matrix[rowIndex].length + 1; k++) {
- if (typeof(matrix[rowIndex][k]) == "undefined") {
- firstAvailCol = k;
- break;
- }
- }
- lookup[cellId] = firstAvailCol;
- for (var k = rowIndex; k < rowIndex + rowSpan; k++) {
- if (typeof(matrix[k]) == "undefined") {
- matrix[k] = [];
- }
- var matrixrow = matrix[k];
- for (var l = firstAvailCol; l < firstAvailCol + colSpan; l++) {
- matrixrow[l] = "x";
- }
- }
- }
- }
- return lookup;
- }
-
- function checkCellColSpan(table, rows, row) {
- var arr = [],
- r = table.tHead.rows,
- c = r[row].cells;
-
- for (var i = 0; i < c.length; i++) {
- var cell = c[i];
-
- if (cell.colSpan > 1) {
- arr = arr.concat(checkCellColSpan(table, headerArr, row++));
- } else {
- if (table.tHead.length == 1 || (cell.rowSpan > 1 || !r[row + 1])) {
- arr.push(cell);
- }
- // headerArr[row] = (i+row);
- }
- }
- return arr;
- };
-
- function checkHeaderMetadata(cell) {
- if (($.metadata) && ($(cell).metadata().sorter === false)) {
- return true;
- };
- return false;
- }
-
- function checkHeaderOptions(table, i) {
- if ((table.config.headers[i]) && (table.config.headers[i].sorter === false)) {
- return true;
- };
- return false;
- }
-
- function checkHeaderOptionsSortingLocked(table, i) {
- if ((table.config.headers[i]) && (table.config.headers[i].lockedOrder)) return table.config.headers[i].lockedOrder;
- return false;
- }
-
- function applyWidget(table) {
- var c = table.config.widgets;
- var l = c.length;
- for (var i = 0; i < l; i++) {
-
- getWidgetById(c[i]).format(table);
- }
-
- }
-
- function getWidgetById(name) {
- var l = widgets.length;
- for (var i = 0; i < l; i++) {
- if (widgets[i].id.toLowerCase() == name.toLowerCase()) {
- return widgets[i];
- }
- }
- };
-
- function formatSortingOrder(v) {
- if (typeof(v) != "Number") {
- return (v.toLowerCase() == "desc") ? 1 : 0;
- } else {
- return (v == 1) ? 1 : 0;
- }
- }
-
- function isValueInArray(v, a) {
- var l = a.length;
- for (var i = 0; i < l; i++) {
- if (a[i][0] == v) {
- return true;
- }
- }
- return false;
- }
-
- function setHeadersCss(table, $headers, list, css) {
- // remove all header information
- $headers.removeClass(css[0]).removeClass(css[1]);
-
- var h = [];
- $headers.each(function (offset) {
- if (!this.sortDisabled) {
- h[this.column] = $(this);
- }
- });
-
- var l = list.length;
- for (var i = 0; i < l; i++) {
- h[list[i][0]].addClass(css[list[i][1]]);
- }
- }
-
- function fixColumnWidth(table, $headers) {
- var c = table.config;
- if (c.widthFixed) {
- var colgroup = $('<colgroup>');
- $("tr:first td", table.tBodies[0]).each(function () {
- colgroup.append($('<col>').css('width', $(this).width()));
- });
- $(table).prepend(colgroup);
- };
- }
-
- function updateHeaderSortCount(table, sortList) {
- var c = table.config,
- l = sortList.length;
- for (var i = 0; i < l; i++) {
- var s = sortList[i],
- o = c.headerList[s[0]];
- o.count = s[1];
- o.count++;
- }
- }
-
- /* sorting methods */
-
- function multisort(table, sortList, cache) {
-
- if (table.config.debug) {
- var sortTime = new Date();
- }
-
- var dynamicExp = "var sortWrapper = function(a,b) {",
- l = sortList.length;
-
- // TODO: inline functions.
- for (var i = 0; i < l; i++) {
-
- var c = sortList[i][0];
- var order = sortList[i][1];
- // var s = (getCachedSortType(table.config.parsers,c) == "text") ?
- // ((order == 0) ? "sortText" : "sortTextDesc") : ((order == 0) ?
- // "sortNumeric" : "sortNumericDesc");
- // var s = (table.config.parsers[c].type == "text") ? ((order == 0)
- // ? makeSortText(c) : makeSortTextDesc(c)) : ((order == 0) ?
- // makeSortNumeric(c) : makeSortNumericDesc(c));
- var s = (table.config.parsers[c].type == "text") ? ((order == 0) ? makeSortFunction("text", "asc", c) : makeSortFunction("text", "desc", c)) : ((order == 0) ? makeSortFunction("numeric", "asc", c) : makeSortFunction("numeric", "desc", c));
- var e = "e" + i;
-
- dynamicExp += "var " + e + " = " + s; // + "(a[" + c + "],b[" + c
- // + "]); ";
- dynamicExp += "if(" + e + ") { return " + e + "; } ";
- dynamicExp += "else { ";
-
- }
-
- // if value is the same keep orignal order
- var orgOrderCol = cache.normalized[0].length - 1;
- dynamicExp += "return a[" + orgOrderCol + "]-b[" + orgOrderCol + "];";
-
- for (var i = 0; i < l; i++) {
- dynamicExp += "}; ";
- }
-
- dynamicExp += "return 0; ";
- dynamicExp += "}; ";
-
- if (table.config.debug) {
- benchmark("Evaling expression:" + dynamicExp, new Date());
- }
-
- eval(dynamicExp);
-
- cache.normalized.sort(sortWrapper);
-
- if (table.config.debug) {
- benchmark("Sorting on " + sortList.toString() + " and dir " + order + " time:", sortTime);
- }
-
- return cache;
- };
-
- function makeSortFunction(type, direction, index) {
- var a = "a[" + index + "]",
- b = "b[" + index + "]";
- if (type == 'text' && direction == 'asc') {
- return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + a + " < " + b + ") ? -1 : 1 )));";
- } else if (type == 'text' && direction == 'desc') {
- return "(" + a + " == " + b + " ? 0 : (" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : (" + b + " < " + a + ") ? -1 : 1 )));";
- } else if (type == 'numeric' && direction == 'asc') {
- return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + a + " - " + b + "));";
- } else if (type == 'numeric' && direction == 'desc') {
- return "(" + a + " === null && " + b + " === null) ? 0 :(" + a + " === null ? Number.POSITIVE_INFINITY : (" + b + " === null ? Number.NEGATIVE_INFINITY : " + b + " - " + a + "));";
- }
- };
-
- function makeSortText(i) {
- return "((a[" + i + "] < b[" + i + "]) ? -1 : ((a[" + i + "] > b[" + i + "]) ? 1 : 0));";
- };
-
- function makeSortTextDesc(i) {
- return "((b[" + i + "] < a[" + i + "]) ? -1 : ((b[" + i + "] > a[" + i + "]) ? 1 : 0));";
- };
-
- function makeSortNumeric(i) {
- return "a[" + i + "]-b[" + i + "];";
- };
-
- function makeSortNumericDesc(i) {
- return "b[" + i + "]-a[" + i + "];";
- };
-
- function sortText(a, b) {
- if (table.config.sortLocaleCompare) return a.localeCompare(b);
- return ((a < b) ? -1 : ((a > b) ? 1 : 0));
- };
-
- function sortTextDesc(a, b) {
- if (table.config.sortLocaleCompare) return b.localeCompare(a);
- return ((b < a) ? -1 : ((b > a) ? 1 : 0));
- };
-
- function sortNumeric(a, b) {
- return a - b;
- };
-
- function sortNumericDesc(a, b) {
- return b - a;
- };
-
- function getCachedSortType(parsers, i) {
- return parsers[i].type;
- }; /* public methods */
- this.construct = function (settings) {
- return this.each(function () {
- // if no thead or tbody quit.
- if (!this.tHead || !this.tBodies) return;
- // declare
- var $this, $document, $headers, cache, config, shiftDown = 0,
- sortOrder;
- // new blank config object
- this.config = {};
- // merge and extend.
- config = $.extend(this.config, $.tablesorter.defaults, settings);
- // store common expression for speed
- $this = $(this);
- // save the settings where they read
- $.data(this, "tablesorter", config);
- // build headers
- $headers = buildHeaders(this);
- // try to auto detect column type, and store in tables config
- this.config.parsers = buildParserCache(this, $headers);
- // build the cache for the tbody cells
- cache = buildCache(this);
- // get the css class names, could be done else where.
- var sortCSS = [config.cssDesc, config.cssAsc];
- // fixate columns if the users supplies the fixedWidth option
- fixColumnWidth(this);
- // apply event handling to headers
- // this is to big, perhaps break it out?
- $headers.click(
-
- function (e) {
- var totalRows = ($this[0].tBodies[0] && $this[0].tBodies[0].rows.length) || 0;
- if (!this.sortDisabled && totalRows > 0) {
- // Only call sortStart if sorting is
- // enabled.
- $this.trigger("sortStart");
- // store exp, for speed
- var $cell = $(this);
- // get current column index
- var i = this.column;
- // get current column sort order
- this.order = this.count++ % 2;
- // always sort on the locked order.
- if(this.lockedOrder) this.order = this.lockedOrder;
-
- // user only whants to sort on one
- // column
- if (!e[config.sortMultiSortKey]) {
- // flush the sort list
- config.sortList = [];
- if (config.sortForce != null) {
- var a = config.sortForce;
- for (var j = 0; j < a.length; j++) {
- if (a[j][0] != i) {
- config.sortList.push(a[j]);
- }
- }
- }
- // add column to sort list
- config.sortList.push([i, this.order]);
- // multi column sorting
- } else {
- // the user has clicked on an all
- // ready sortet column.
- if (isValueInArray(i, config.sortList)) {
- // revers the sorting direction
- // for all tables.
- for (var j = 0; j < config.sortList.length; j++) {
- var s = config.sortList[j],
- o = config.headerList[s[0]];
- if (s[0] == i) {
- o.count = s[1];
- o.count++;
- s[1] = o.count % 2;
- }
- }
- } else {
- // add column to sort list array
- config.sortList.push([i, this.order]);
- }
- };
- setTimeout(function () {
- // set css for headers
- setHeadersCss($this[0], $headers, config.sortList, sortCSS);
- appendToTable(
- $this[0], multisort(
- $this[0], config.sortList, cache)
- );
- }, 1);
- // stop normal event by returning false
- return false;
- }
- // cancel selection
- }).mousedown(function () {
- if (config.cancelSelection) {
- this.onselectstart = function () {
- return false
- };
- return false;
- }
- });
- // apply easy methods that trigger binded events
- $this.bind("update", function () {
- var me = this;
- setTimeout(function () {
- // rebuild parsers.
- me.config.parsers = buildParserCache(
- me, $headers);
- // rebuild the cache map
- cache = buildCache(me);
- }, 1);
- }).bind("updateCell", function (e, cell) {
- var config = this.config;
- // get position from the dom.
- var pos = [(cell.parentNode.rowIndex - 1), cell.cellIndex];
- // update cache
- cache.normalized[pos[0]][pos[1]] = config.parsers[pos[1]].format(
- getElementText(config, cell), cell);
- }).bind("sorton", function (e, list) {
- $(this).trigger("sortStart");
- config.sortList = list;
- // update and store the sortlist
- var sortList = config.sortList;
- // update header count index
- updateHeaderSortCount(this, sortList);
- // set css for headers
- setHeadersCss(this, $headers, sortList, sortCSS);
- // sort the table and append it to the dom
- appendToTable(this, multisort(this, sortList, cache));
- }).bind("appendCache", function () {
- appendToTable(this, cache);
- }).bind("applyWidgetId", function (e, id) {
- getWidgetById(id).format(this);
- }).bind("applyWidgets", function () {
- // apply widgets
- applyWidget(this);
- });
- if ($.metadata && ($(this).metadata() && $(this).metadata().sortlist)) {
- config.sortList = $(this).metadata().sortlist;
- }
- // if user has supplied a sort list to constructor.
- if (config.sortList.length > 0) {
- $this.trigger("sorton", [config.sortList]);
- }
- // apply widgets
- applyWidget(this);
- });
- };
- this.addParser = function (parser) {
- var l = parsers.length,
- a = true;
- for (var i = 0; i < l; i++) {
- if (parsers[i].id.toLowerCase() == parser.id.toLowerCase()) {
- a = false;
- }
- }
- if (a) {
- parsers.push(parser);
- };
- };
- this.addWidget = function (widget) {
- widgets.push(widget);
- };
- this.formatFloat = function (s) {
- var i = parseFloat(s);
- return (isNaN(i)) ? 0 : i;
- };
- this.formatInt = function (s) {
- var i = parseInt(s);
- return (isNaN(i)) ? 0 : i;
- };
- this.isDigit = function (s, config) {
- // replace all unwanted chars and match.
- return /^[-+]?\d*$/.test($.trim(s.replace(/[,.']/g, '')));
- };
- this.clearTableBody = function (table) {
- if ($.browser.msie) {
- function empty() {
- while (this.firstChild)
- this.removeChild(this.firstChild);
- }
- empty.apply(table.tBodies[0]);
- } else {
- table.tBodies[0].innerHTML = "";
- }
- };
- }
- });
-
- // extend plugin scope
- $.fn.extend({
- tablesorter: $.tablesorter.construct
- });
-
- // make shortcut
- var ts = $.tablesorter;
-
- // add default parsers
- ts.addParser({
- id: "text",
- is: function (s) {
- return true;
- }, format: function (s) {
- return $.trim(s.toLocaleLowerCase());
- }, type: "text"
- });
-
- ts.addParser({
- id: "digit",
- is: function (s, table) {
- var c = table.config;
- return $.tablesorter.isDigit(s, c);
- }, format: function (s) {
- return $.tablesorter.formatFloat(s);
- }, type: "numeric"
- });
-
- ts.addParser({
- id: "currency",
- is: function (s) {
- return /^[£$€?.]/.test(s);
- }, format: function (s) {
- return $.tablesorter.formatFloat(s.replace(new RegExp(/[£$€]/g), ""));
- }, type: "numeric"
- });
-
- ts.addParser({
- id: "ipAddress",
- is: function (s) {
- return /^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s);
- }, format: function (s) {
- var a = s.split("."),
- r = "",
- l = a.length;
- for (var i = 0; i < l; i++) {
- var item = a[i];
- if (item.length == 2) {
- r += "0" + item;
- } else {
- r += item;
- }
- }
- return $.tablesorter.formatFloat(r);
- }, type: "numeric"
- });
-
- ts.addParser({
- id: "url",
- is: function (s) {
- return /^(https?|ftp|file):\/\/$/.test(s);
- }, format: function (s) {
- return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//), ''));
- }, type: "text"
- });
-
- ts.addParser({
- id: "isoDate",
- is: function (s) {
- return /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s);
- }, format: function (s) {
- return $.tablesorter.formatFloat((s != "") ? new Date(s.replace(
- new RegExp(/-/g), "/")).getTime() : "0");
- }, type: "numeric"
- });
-
- ts.addParser({
- id: "percent",
- is: function (s) {
- return /\%$/.test($.trim(s));
- }, format: function (s) {
- return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g), ""));
- }, type: "numeric"
- });
-
- ts.addParser({
- id: "usLongDate",
- is: function (s) {
- return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/));
- }, format: function (s) {
- return $.tablesorter.formatFloat(new Date(s).getTime());
- }, type: "numeric"
- });
-
- ts.addParser({
- id: "shortDate",
- is: function (s) {
- return /\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/.test(s);
- }, format: function (s, table) {
- var c = table.config;
- s = s.replace(/\-/g, "/");
- if (c.dateFormat == "us") {
- // reformat the string in ISO format
- s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$1/$2");
- } else if (c.dateFormat == "uk") {
- // reformat the string in ISO format
- s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$2/$1");
- } else if (c.dateFormat == "dd/mm/yy" || c.dateFormat == "dd-mm-yy") {
- s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/, "$1/$2/$3");
- }
- return $.tablesorter.formatFloat(new Date(s).getTime());
- }, type: "numeric"
- });
- ts.addParser({
- id: "time",
- is: function (s) {
- return /^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s);
- }, format: function (s) {
- return $.tablesorter.formatFloat(new Date("2000/01/01 " + s).getTime());
- }, type: "numeric"
- });
- ts.addParser({
- id: "metadata",
- is: function (s) {
- return false;
- }, format: function (s, table, cell) {
- var c = table.config,
- p = (!c.parserMetadataName) ? 'sortValue' : c.parserMetadataName;
- return $(cell).metadata()[p];
- }, type: "numeric"
- });
- // add default widgets
- ts.addWidget({
- id: "zebra",
- format: function (table) {
- if (table.config.debug) {
- var time = new Date();
- }
- var $tr, row = -1,
- odd;
- // loop through the visible rows
- $("tr:visible", table.tBodies[0]).each(function (i) {
- $tr = $(this);
- // style children rows the same way the parent
- // row was styled
- if (!$tr.hasClass(table.config.cssChildRow)) row++;
- odd = (row % 2 == 0);
- $tr.removeClass(
- table.config.widgetZebra.css[odd ? 0 : 1]).addClass(
- table.config.widgetZebra.css[odd ? 1 : 0])
- });
- if (table.config.debug) {
- $.tablesorter.benchmark("Applying Zebra widget", time);
- }
- }
- });
-})(jQuery);
diff --git a/horizon/static/horizon/lib/json2.js b/horizon/static/horizon/lib/json2.js
deleted file mode 100644
index 3b0c872d..00000000
--- a/horizon/static/horizon/lib/json2.js
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- json2.js
- 2011-10-19
-
- Public Domain.
-
- NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
-
- See http://www.JSON.org/js.html
-
-
- This code should be minified before deployment.
- See http://javascript.crockford.com/jsmin.html
-
- USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
- NOT CONTROL.
-
-
- This file creates a global JSON object containing two methods: stringify
- and parse.
-
- JSON.stringify(value, replacer, space)
- value any JavaScript value, usually an object or array.
-
- replacer an optional parameter that determines how object
- values are stringified for objects. It can be a
- function or an array of strings.
-
- space an optional parameter that specifies the indentation
- of nested structures. If it is omitted, the text will
- be packed without extra whitespace. If it is a number,
- it will specify the number of spaces to indent at each
- level. If it is a string (such as '\t' or '&nbsp;'),
- it contains the characters used to indent at each level.
-
- This method produces a JSON text from a JavaScript value.
-
- When an object value is found, if the object contains a toJSON
- method, its toJSON method will be called and the result will be
- stringified. A toJSON method does not serialize: it returns the
- value represented by the name/value pair that should be serialized,
- or undefined if nothing should be serialized. The toJSON method
- will be passed the key associated with the value, and this will be
- bound to the value
-
- For example, this would serialize Dates as ISO strings.
-
- Date.prototype.toJSON = function (key) {
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- return this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z';
- };
-
- You can provide an optional replacer method. It will be passed the
- key and value of each member, with this bound to the containing
- object. The value that is returned from your method will be
- serialized. If your method returns undefined, then the member will
- be excluded from the serialization.
-
- If the replacer parameter is an array of strings, then it will be
- used to select the members to be serialized. It filters the results
- such that only members with keys listed in the replacer array are
- stringified.
-
- Values that do not have JSON representations, such as undefined or
- functions, will not be serialized. Such values in objects will be
- dropped; in arrays they will be replaced with null. You can use
- a replacer function to replace those with JSON values.
- JSON.stringify(undefined) returns undefined.
-
- The optional space parameter produces a stringification of the
- value that is filled with line breaks and indentation to make it
- easier to read.
-
- If the space parameter is a non-empty string, then that string will
- be used for indentation. If the space parameter is a number, then
- the indentation will be that many spaces.
-
- Example:
-
- text = JSON.stringify(['e', {pluribus: 'unum'}]);
- // text is '["e",{"pluribus":"unum"}]'
-
-
- text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
- // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
-
- text = JSON.stringify([new Date()], function (key, value) {
- return this[key] instanceof Date ?
- 'Date(' + this[key] + ')' : value;
- });
- // text is '["Date(---current time---)"]'
-
-
- JSON.parse(text, reviver)
- This method parses a JSON text to produce an object or array.
- It can throw a SyntaxError exception.
-
- The optional reviver parameter is a function that can filter and
- transform the results. It receives each of the keys and values,
- and its return value is used instead of the original value.
- If it returns what it received, then the structure is not modified.
- If it returns undefined then the member is deleted.
-
- Example:
-
- // Parse the text. Values that look like ISO date strings will
- // be converted to Date objects.
-
- myData = JSON.parse(text, function (key, value) {
- var a;
- if (typeof value === 'string') {
- a =
-/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
- if (a) {
- return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
- +a[5], +a[6]));
- }
- }
- return value;
- });
-
- myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
- var d;
- if (typeof value === 'string' &&
- value.slice(0, 5) === 'Date(' &&
- value.slice(-1) === ')') {
- d = new Date(value.slice(5, -1));
- if (d) {
- return d;
- }
- }
- return value;
- });
-
-
- This is a reference implementation. You are free to copy, modify, or
- redistribute.
-*/
-
-/*jslint evil: true, regexp: true */
-
-/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
- call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
- getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
- lastIndex, length, parse, prototype, push, replace, slice, stringify,
- test, toJSON, toString, valueOf
-*/
-
-
-// Create a JSON object only if one does not already exist. We create the
-// methods in a closure to avoid creating global variables.
-
-var JSON;
-if (!JSON) {
- JSON = {};
-}
-
-(function () {
- 'use strict';
-
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- if (typeof Date.prototype.toJSON !== 'function') {
-
- Date.prototype.toJSON = function (key) {
-
- return isFinite(this.valueOf())
- ? this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z'
- : null;
- };
-
- String.prototype.toJSON =
- Number.prototype.toJSON =
- Boolean.prototype.toJSON = function (key) {
- return this.valueOf();
- };
- }
-
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- gap,
- indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- },
- rep;
-
-
- function quote(string) {
-
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can safely slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe escape
-// sequences.
-
- escapable.lastIndex = 0;
- return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string'
- ? c
- : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' : '"' + string + '"';
- }
-
-
- function str(key, holder) {
-
-// Produce a string from holder[key].
-
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
-
-// If the value has a toJSON method, call it to obtain a replacement value.
-
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
-
-// If we were called with a replacer function, then call the replacer to
-// obtain a replacement value.
-
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
-
-// What happens next depends on the value's type.
-
- switch (typeof value) {
- case 'string':
- return quote(value);
-
- case 'number':
-
-// JSON numbers must be finite. Encode non-finite numbers as null.
-
- return isFinite(value) ? String(value) : 'null';
-
- case 'boolean':
- case 'null':
-
-// If the value is a boolean or null, convert it to a string. Note:
-// typeof null does not produce 'null'. The case is included here in
-// the remote chance that this gets fixed someday.
-
- return String(value);
-
-// If the type is 'object', we might be dealing with an object or an array or
-// null.
-
- case 'object':
-
-// Due to a specification blunder in ECMAScript, typeof null is 'object',
-// so watch out for that case.
-
- if (!value) {
- return 'null';
- }
-
-// Make an array to hold the partial results of stringifying this object value.
-
- gap += indent;
- partial = [];
-
-// Is the value an array?
-
- if (Object.prototype.toString.apply(value) === '[object Array]') {
-
-// The value is an array. Stringify every element. Use null as a placeholder
-// for non-JSON values.
-
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
-
-// Join all of the elements together, separated with commas, and wrap them in
-// brackets.
-
- v = partial.length === 0
- ? '[]'
- : gap
- ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
- : '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
-
-// If the replacer is an array, use it to select the members to be stringified.
-
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- if (typeof rep[i] === 'string') {
- k = rep[i];
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
-
-// Otherwise, iterate through all of the keys in the object.
-
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
-
-// Join all of the member texts together, separated with commas,
-// and wrap them in braces.
-
- v = partial.length === 0
- ? '{}'
- : gap
- ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
- : '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
-
-// If the JSON object does not yet have a stringify method, give it one.
-
- if (typeof JSON.stringify !== 'function') {
- JSON.stringify = function (value, replacer, space) {
-
-// The stringify method takes a value and an optional replacer, and an optional
-// space parameter, and returns a JSON text. The replacer can be a function
-// that can replace values, or an array of strings that will select the keys.
-// A default replacer method can be provided. Use of the space parameter can
-// produce text that is more easily readable.
-
- var i;
- gap = '';
- indent = '';
-
-// If the space parameter is a number, make an indent string containing that
-// many spaces.
-
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
-
-// If the space parameter is a string, it will be used as the indent string.
-
- } else if (typeof space === 'string') {
- indent = space;
- }
-
-// If there is a replacer, it must be a function or an array.
-// Otherwise, throw an error.
-
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
-
-// Make a fake root object containing our value under the key of ''.
-// Return the result of stringifying the value.
-
- return str('', {'': value});
- };
- }
-
-
-// If the JSON object does not yet have a parse method, give it one.
-
- if (typeof JSON.parse !== 'function') {
- JSON.parse = function (text, reviver) {
-
-// The parse method takes a text and an optional reviver function, and returns
-// a JavaScript value if the text is a valid JSON text.
-
- var j;
-
- function walk(holder, key) {
-
-// The walk method is used to recursively walk the resulting structure so
-// that modifications can be made.
-
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
-
-
-// Parsing happens in four stages. In the first stage, we replace certain
-// Unicode characters with escape sequences. JavaScript handles many characters
-// incorrectly, either silently deleting them, or treating them as line endings.
-
- text = String(text);
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
-// In the second stage, we run the text against regular expressions that look
-// for non-JSON patterns. We are especially concerned with '()' and 'new'
-// because they can cause invocation, and '=' because it can cause mutation.
-// But just to be safe, we want to reject all unexpected forms.
-
-// We split the second stage into 4 regexp operations in order to work around
-// crippling inefficiencies in IE's and Safari's regexp engines. First we
-// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
-// replace all simple value tokens with ']' characters. Third, we delete all
-// open brackets that follow a colon or comma or that begin the text. Finally,
-// we look to see that the remaining characters are only whitespace or ']' or
-// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
-
- if (/^[\],:{}\s]*$/
- .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
- .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
- .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
-// In the third stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
- j = eval('(' + text + ')');
-
-// In the optional fourth stage, we recursively walk the new structure, passing
-// each name/value pair to a reviver function for possible transformation.
-
- return typeof reviver === 'function'
- ? walk({'': j}, '')
- : j;
- }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
- throw new SyntaxError('JSON.parse');
- };
- }
-}());
diff --git a/horizon/static/horizon/lib/qunit/qunit.css b/horizon/static/horizon/lib/qunit/qunit.css
deleted file mode 100644
index b3cb0704..00000000
--- a/horizon/static/horizon/lib/qunit/qunit.css
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- * QUnit v1.9.0pre - A JavaScript Unit Testing Framework
- *
- * http://docs.jquery.com/QUnit
- *
- * Copyright (c) 2012 John Resig, Jörn Zaefferer
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * or GPL (GPL-LICENSE.txt) licenses.
- * Pulled Live from Git Sat Jun 23 20:50:01 UTC 2012
- * Last Commit: 1c0af4e943400de73bc36310d3db42a5217da215
- */
-
-/** Font Family and Sizes */
-
-#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
- font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
-}
-
-#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
-#qunit-tests { font-size: smaller; }
-
-
-/** Resets */
-
-#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
- margin: 0;
- padding: 0;
-}
-
-
-/** Header */
-
-#qunit-header {
- padding: 0.5em 0 0.5em 1em;
-
- color: #8699a4;
- background-color: #0d3349;
-
- font-size: 1.5em;
- line-height: 1em;
- font-weight: normal;
-
- border-radius: 15px 15px 0 0;
- -moz-border-radius: 15px 15px 0 0;
- -webkit-border-top-right-radius: 15px;
- -webkit-border-top-left-radius: 15px;
-}
-
-#qunit-header a {
- text-decoration: none;
- color: #c2ccd1;
-}
-
-#qunit-header a:hover,
-#qunit-header a:focus {
- color: #fff;
-}
-
-#qunit-header label {
- display: inline-block;
- padding-left: 0.5em;
-}
-
-#qunit-banner {
- height: 5px;
-}
-
-#qunit-testrunner-toolbar {
- padding: 0.5em 0 0.5em 2em;
- color: #5E740B;
- background-color: #eee;
-}
-
-#qunit-userAgent {
- padding: 0.5em 0 0.5em 2.5em;
- background-color: #2b81af;
- color: #fff;
- text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
-}
-
-
-/** Tests: Pass/Fail */
-
-#qunit-tests {
- list-style-position: inside;
-}
-
-#qunit-tests li {
- padding: 0.4em 0.5em 0.4em 2.5em;
- border-bottom: 1px solid #fff;
- list-style-position: inside;
-}
-
-#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
- display: none;
-}
-
-#qunit-tests li strong {
- cursor: pointer;
-}
-
-#qunit-tests li a {
- padding: 0.5em;
- color: #c2ccd1;
- text-decoration: none;
-}
-#qunit-tests li a:hover,
-#qunit-tests li a:focus {
- color: #000;
-}
-
-#qunit-tests ol {
- margin-top: 0.5em;
- padding: 0.5em;
-
- background-color: #fff;
-
- border-radius: 15px;
- -moz-border-radius: 15px;
- -webkit-border-radius: 15px;
-
- box-shadow: inset 0px 2px 13px #999;
- -moz-box-shadow: inset 0px 2px 13px #999;
- -webkit-box-shadow: inset 0px 2px 13px #999;
-}
-
-#qunit-tests table {
- border-collapse: collapse;
- margin-top: .2em;
-}
-
-#qunit-tests th {
- text-align: right;
- vertical-align: top;
- padding: 0 .5em 0 0;
-}
-
-#qunit-tests td {
- vertical-align: top;
-}
-
-#qunit-tests pre {
- margin: 0;
- white-space: pre-wrap;
- word-wrap: break-word;
-}
-
-#qunit-tests del {
- background-color: #e0f2be;
- color: #374e0c;
- text-decoration: none;
-}
-
-#qunit-tests ins {
- background-color: #ffcaca;
- color: #500;
- text-decoration: none;
-}
-
-/*** Test Counts */
-
-#qunit-tests b.counts { color: black; }
-#qunit-tests b.passed { color: #5E740B; }
-#qunit-tests b.failed { color: #710909; }
-
-#qunit-tests li li {
- margin: 0.5em;
- padding: 0.4em 0.5em 0.4em 0.5em;
- background-color: #fff;
- border-bottom: none;
- list-style-position: inside;
-}
-
-/*** Passing Styles */
-
-#qunit-tests li li.pass {
- color: #5E740B;
- background-color: #fff;
- border-left: 26px solid #C6E746;
-}
-
-#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
-#qunit-tests .pass .test-name { color: #366097; }
-
-#qunit-tests .pass .test-actual,
-#qunit-tests .pass .test-expected { color: #999999; }
-
-#qunit-banner.qunit-pass { background-color: #C6E746; }
-
-/*** Failing Styles */
-
-#qunit-tests li li.fail {
- color: #710909;
- background-color: #fff;
- border-left: 26px solid #EE5757;
- white-space: pre;
-}
-
-#qunit-tests > li:last-child {
- border-radius: 0 0 15px 15px;
- -moz-border-radius: 0 0 15px 15px;
- -webkit-border-bottom-right-radius: 15px;
- -webkit-border-bottom-left-radius: 15px;
-}
-
-#qunit-tests .fail { color: #000000; background-color: #EE5757; }
-#qunit-tests .fail .test-name,
-#qunit-tests .fail .module-name { color: #000000; }
-
-#qunit-tests .fail .test-actual { color: #EE5757; }
-#qunit-tests .fail .test-expected { color: green; }
-
-#qunit-banner.qunit-fail { background-color: #EE5757; }
-
-
-/** Result */
-
-#qunit-testresult {
- padding: 0.5em 0.5em 0.5em 2.5em;
-
- color: #2b81af;
- background-color: #D2E0E6;
-
- border-bottom: 1px solid white;
-}
-#qunit-testresult .module-name {
- font-weight: bold;
-}
-
-/** Fixture */
-
-#qunit-fixture {
- position: absolute;
- top: -10000px;
- left: -10000px;
- width: 1000px;
- height: 1000px;
-}
diff --git a/horizon/static/horizon/lib/qunit/qunit.js b/horizon/static/horizon/lib/qunit/qunit.js
deleted file mode 100644
index 87f9fb74..00000000
--- a/horizon/static/horizon/lib/qunit/qunit.js
+++ /dev/null
@@ -1,1865 +0,0 @@
-/**
- * QUnit v1.9.0pre - A JavaScript Unit Testing Framework
- *
- * http://docs.jquery.com/QUnit
- *
- * Copyright (c) 2012 John Resig, Jörn Zaefferer
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * or GPL (GPL-LICENSE.txt) licenses.
- * Pulled Live from Git Sat Jun 23 20:50:01 UTC 2012
- * Last Commit: 1c0af4e943400de73bc36310d3db42a5217da215
- */
-
-(function( window ) {
-
-var QUnit,
- config,
- onErrorFnPrev,
- testId = 0,
- fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
- toString = Object.prototype.toString,
- hasOwn = Object.prototype.hasOwnProperty,
- defined = {
- setTimeout: typeof window.setTimeout !== "undefined",
- sessionStorage: (function() {
- var x = "qunit-test-string";
- try {
- sessionStorage.setItem( x, x );
- sessionStorage.removeItem( x );
- return true;
- } catch( e ) {
- return false;
- }
- }())
-};
-
-function Test( settings ) {
- extend( this, settings );
- this.assertions = [];
- this.testNumber = ++Test.count;
-}
-
-Test.count = 0;
-
-Test.prototype = {
- init: function() {
- var a, b, li,
- tests = id( "qunit-tests" );
-
- if ( tests ) {
- b = document.createElement( "strong" );
- b.innerHTML = this.name;
-
- // `a` initialized at top of scope
- a = document.createElement( "a" );
- a.innerHTML = "Rerun";
- a.href = QUnit.url({ testNumber: this.testNumber });
-
- li = document.createElement( "li" );
- li.appendChild( b );
- li.appendChild( a );
- li.className = "running";
- li.id = this.id = "qunit-test-output" + testId++;
-
- tests.appendChild( li );
- }
- },
- setup: function() {
- if ( this.module !== config.previousModule ) {
- if ( config.previousModule ) {
- runLoggingCallbacks( "moduleDone", QUnit, {
- name: config.previousModule,
- failed: config.moduleStats.bad,
- passed: config.moduleStats.all - config.moduleStats.bad,
- total: config.moduleStats.all
- });
- }
- config.previousModule = this.module;
- config.moduleStats = { all: 0, bad: 0 };
- runLoggingCallbacks( "moduleStart", QUnit, {
- name: this.module
- });
- } else if ( config.autorun ) {
- runLoggingCallbacks( "moduleStart", QUnit, {
- name: this.module
- });
- }
-
- config.current = this;
-
- this.testEnvironment = extend({
- setup: function() {},
- teardown: function() {}
- }, this.moduleTestEnvironment );
-
- runLoggingCallbacks( "testStart", QUnit, {
- name: this.testName,
- module: this.module
- });
-
- // allow utility functions to access the current test environment
- // TODO why??
- QUnit.current_testEnvironment = this.testEnvironment;
-
- if ( !config.pollution ) {
- saveGlobal();
- }
- if ( config.notrycatch ) {
- this.testEnvironment.setup.call( this.testEnvironment );
- return;
- }
- try {
- this.testEnvironment.setup.call( this.testEnvironment );
- } catch( e ) {
- QUnit.pushFailure( "Setup failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );
- }
- },
- run: function() {
- config.current = this;
-
- var running = id( "qunit-testresult" );
-
- if ( running ) {
- running.innerHTML = "Running: <br/>" + this.name;
- }
-
- if ( this.async ) {
- QUnit.stop();
- }
-
- if ( config.notrycatch ) {
- this.callback.call( this.testEnvironment, QUnit.assert );
- return;
- }
-
- try {
- this.callback.call( this.testEnvironment, QUnit.assert );
- } catch( e ) {
- QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + e.message, extractStacktrace( e, 0 ) );
- // else next test will carry the responsibility
- saveGlobal();
-
- // Restart the tests if they're blocking
- if ( config.blocking ) {
- QUnit.start();
- }
- }
- },
- teardown: function() {
- config.current = this;
- if ( config.notrycatch ) {
- this.testEnvironment.teardown.call( this.testEnvironment );
- return;
- } else {
- try {
- this.testEnvironment.teardown.call( this.testEnvironment );
- } catch( e ) {
- QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + e.message, extractStacktrace( e, 1 ) );
- }
- }
- checkPollution();
- },
- finish: function() {
- config.current = this;
- if ( config.requireExpects && this.expected == null ) {
- QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
- } else if ( this.expected != null && this.expected != this.assertions.length ) {
- QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
- } else if ( this.expected == null && !this.assertions.length ) {
- QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
- }
-
- var assertion, a, b, i, li, ol,
- test = this,
- good = 0,
- bad = 0,
- tests = id( "qunit-tests" );
-
- config.stats.all += this.assertions.length;
- config.moduleStats.all += this.assertions.length;
-
- if ( tests ) {
- ol = document.createElement( "ol" );
-
- for ( i = 0; i < this.assertions.length; i++ ) {
- assertion = this.assertions[i];
-
- li = document.createElement( "li" );
- li.className = assertion.result ? "pass" : "fail";
- li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" );
- ol.appendChild( li );
-
- if ( assertion.result ) {
- good++;
- } else {
- bad++;
- config.stats.bad++;
- config.moduleStats.bad++;
- }
- }
-
- // store result when possible
- if ( QUnit.config.reorder && defined.sessionStorage ) {
- if ( bad ) {
- sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad );
- } else {
- sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName );
- }
- }
-
- if ( bad === 0 ) {
- ol.style.display = "none";
- }
-
- // `b` initialized at top of scope
- b = document.createElement( "strong" );
- b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
-
- addEvent(b, "click", function() {
- var next = b.nextSibling.nextSibling,
- display = next.style.display;
- next.style.display = display === "none" ? "block" : "none";
- });
-
- addEvent(b, "dblclick", function( e ) {
- var target = e && e.target ? e.target : window.event.srcElement;
- if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
- target = target.parentNode;
- }
- if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
- window.location = QUnit.url({ testNumber: test.testNumber });
- }
- });
-
- // `li` initialized at top of scope
- li = id( this.id );
- li.className = bad ? "fail" : "pass";
- li.removeChild( li.firstChild );
- a = li.firstChild;
- li.appendChild( b );
- li.appendChild ( a );
- li.appendChild( ol );
-
- } else {
- for ( i = 0; i < this.assertions.length; i++ ) {
- if ( !this.assertions[i].result ) {
- bad++;
- config.stats.bad++;
- config.moduleStats.bad++;
- }
- }
- }
-
- runLoggingCallbacks( "testDone", QUnit, {
- name: this.testName,
- module: this.module,
- failed: bad,
- passed: this.assertions.length - bad,
- total: this.assertions.length
- });
-
- QUnit.reset();
-
- config.current = undefined;
- },
-
- queue: function() {
- var bad,
- test = this;
-
- synchronize(function() {
- test.init();
- });
- function run() {
- // each of these can by async
- synchronize(function() {
- test.setup();
- });
- synchronize(function() {
- test.run();
- });
- synchronize(function() {
- test.teardown();
- });
- synchronize(function() {
- test.finish();
- });
- }
-
- // `bad` initialized at top of scope
- // defer when previous test run passed, if storage is available
- bad = QUnit.config.reorder && defined.sessionStorage &&
- +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName );
-
- if ( bad ) {
- run();
- } else {
- synchronize( run, true );
- }
- }
-};
-
-// Root QUnit object.
-// `QUnit` initialized at top of scope
-QUnit = {
-
- // call on start of module test to prepend name to all tests
- module: function( name, testEnvironment ) {
- config.currentModule = name;
- config.currentModuleTestEnviroment = testEnvironment;
- },
-
- asyncTest: function( testName, expected, callback ) {
- if ( arguments.length === 2 ) {
- callback = expected;
- expected = null;
- }
-
- QUnit.test( testName, expected, callback, true );
- },
-
- test: function( testName, expected, callback, async ) {
- var test,
- name = "<span class='test-name'>" + escapeInnerText( testName ) + "</span>";
-
- if ( arguments.length === 2 ) {
- callback = expected;
- expected = null;
- }
-
- if ( config.currentModule ) {
- name = "<span class='module-name'>" + config.currentModule + "</span>: " + name;
- }
-
- test = new Test({
- name: name,
- testName: testName,
- expected: expected,
- async: async,
- callback: callback,
- module: config.currentModule,
- moduleTestEnvironment: config.currentModuleTestEnviroment,
- stack: sourceFromStacktrace( 2 )
- });
-
- if ( !validTest( test ) ) {
- return;
- }
-
- test.queue();
- },
-
- // Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
- expect: function( asserts ) {
- config.current.expected = asserts;
- },
-
- start: function( count ) {
- config.semaphore -= count || 1;
- // don't start until equal number of stop-calls
- if ( config.semaphore > 0 ) {
- return;
- }
- // ignore if start is called more often then stop
- if ( config.semaphore < 0 ) {
- config.semaphore = 0;
- }
- // A slight delay, to avoid any current callbacks
- if ( defined.setTimeout ) {
- window.setTimeout(function() {
- if ( config.semaphore > 0 ) {
- return;
- }
- if ( config.timeout ) {
- clearTimeout( config.timeout );
- }
-
- config.blocking = false;
- process( true );
- }, 13);
- } else {
- config.blocking = false;
- process( true );
- }
- },
-
- stop: function( count ) {
- config.semaphore += count || 1;
- config.blocking = true;
-
- if ( config.testTimeout && defined.setTimeout ) {
- clearTimeout( config.timeout );
- config.timeout = window.setTimeout(function() {
- QUnit.ok( false, "Test timed out" );
- config.semaphore = 1;
- QUnit.start();
- }, config.testTimeout );
- }
- }
-};
-
-// Asssert helpers
-// All of these must call either QUnit.push() or manually do:
-// - runLoggingCallbacks( "log", .. );
-// - config.current.assertions.push({ .. });
-QUnit.assert = {
- /**
- * Asserts rough true-ish result.
- * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
- */
- ok: function( result, msg ) {
- if ( !config.current ) {
- throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
- }
- result = !!result;
-
- var source,
- details = {
- result: result,
- message: msg
- };
-
- msg = escapeInnerText( msg || (result ? "okay" : "failed" ) );
- msg = "<span class='test-message'>" + msg + "</span>";
-
- if ( !result ) {
- source = sourceFromStacktrace( 2 );
- if ( source ) {
- details.source = source;
- msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr></table>";
- }
- }
- runLoggingCallbacks( "log", QUnit, details );
- config.current.assertions.push({
- result: result,
- message: msg
- });
- },
-
- /**
- * Assert that the first two arguments are equal, with an optional message.
- * Prints out both actual and expected values.
- * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
- */
- equal: function( actual, expected, message ) {
- QUnit.push( expected == actual, actual, expected, message );
- },
-
- notEqual: function( actual, expected, message ) {
- QUnit.push( expected != actual, actual, expected, message );
- },
-
- deepEqual: function( actual, expected, message ) {
- QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
- },
-
- notDeepEqual: function( actual, expected, message ) {
- QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
- },
-
- strictEqual: function( actual, expected, message ) {
- QUnit.push( expected === actual, actual, expected, message );
- },
-
- notStrictEqual: function( actual, expected, message ) {
- QUnit.push( expected !== actual, actual, expected, message );
- },
-
- raises: function( block, expected, message ) {
- var actual,
- ok = false;
-
- if ( typeof expected === "string" ) {
- message = expected;
- expected = null;
- }
-
- config.current.ignoreGlobalErrors = true;
- try {
- block.call( config.current.testEnvironment );
- } catch (e) {
- actual = e;
- }
- config.current.ignoreGlobalErrors = false;
-
- if ( actual ) {
- // we don't want to validate thrown error
- if ( !expected ) {
- ok = true;
- // expected is a regexp
- } else if ( QUnit.objectType( expected ) === "regexp" ) {
- ok = expected.test( actual );
- // expected is a constructor
- } else if ( actual instanceof expected ) {
- ok = true;
- // expected is a validation function which returns true is validation passed
- } else if ( expected.call( {}, actual ) === true ) {
- ok = true;
- }
- }
-
- QUnit.push( ok, actual, null, message );
- }
-};
-
-// @deprecated: Kept assertion helpers in root for backwards compatibility
-extend( QUnit, QUnit.assert );
-
-/**
- * @deprecated: Kept for backwards compatibility
- * next step: remove entirely
- */
-QUnit.equals = function() {
- QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
-};
-QUnit.same = function() {
- QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
-};
-
-// We want access to the constructor's prototype
-(function() {
- function F() {}
- F.prototype = QUnit;
- QUnit = new F();
- // Make F QUnit's constructor so that we can add to the prototype later
- QUnit.constructor = F;
-}());
-
-/**
- * Config object: Maintain internal state
- * Later exposed as QUnit.config
- * `config` initialized at top of scope
- */
-config = {
- // The queue of tests to run
- queue: [],
-
- // block until document ready
- blocking: true,
-
- // when enabled, show only failing tests
- // gets persisted through sessionStorage and can be changed in UI via checkbox
- hidepassed: false,
-
- // by default, run previously failed tests first
- // very useful in combination with "Hide passed tests" checked
- reorder: true,
-
- // by default, modify document.title when suite is done
- altertitle: true,
-
- // when enabled, all tests must call expect()
- requireExpects: false,
-
- urlConfig: [ "noglobals", "notrycatch" ],
-
- // logging callback queues
- begin: [],
- done: [],
- log: [],
- testStart: [],
- testDone: [],
- moduleStart: [],
- moduleDone: []
-};
-
-// Initialize more QUnit.config and QUnit.urlParams
-(function() {
- var i,
- location = window.location || { search: "", protocol: "file:" },
- params = location.search.slice( 1 ).split( "&" ),
- length = params.length,
- urlParams = {},
- current;
-
- if ( params[ 0 ] ) {
- for ( i = 0; i < length; i++ ) {
- current = params[ i ].split( "=" );
- current[ 0 ] = decodeURIComponent( current[ 0 ] );
- // allow just a key to turn on a flag, e.g., test.html?noglobals
- current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
- urlParams[ current[ 0 ] ] = current[ 1 ];
- }
- }
-
- QUnit.urlParams = urlParams;
-
- // String search anywhere in moduleName+testName
- config.filter = urlParams.filter;
-
- // Exact match of the module name
- config.module = urlParams.module;
-
- config.testNumber = parseInt( urlParams.testNumber, 10 ) || null;
-
- // Figure out if we're running the tests from a server or not
- QUnit.isLocal = location.protocol === "file:";
-}());
-
-// Export global variables, unless an 'exports' object exists,
-// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
-if ( typeof exports === "undefined" ) {
- extend( window, QUnit );
-
- // Expose QUnit object
- window.QUnit = QUnit;
-}
-
-// Extend QUnit object,
-// these after set here because they should not be exposed as global functions
-extend( QUnit, {
- config: config,
-
- // Initialize the configuration options
- init: function() {
- extend( config, {
- stats: { all: 0, bad: 0 },
- moduleStats: { all: 0, bad: 0 },
- started: +new Date(),
- updateRate: 1000,
- blocking: false,
- autostart: true,
- autorun: false,
- filter: "",
- queue: [],
- semaphore: 0
- });
-
- var tests, banner, result,
- qunit = id( "qunit" );
-
- if ( qunit ) {
- qunit.innerHTML =
- "<h1 id='qunit-header'>" + escapeInnerText( document.title ) + "</h1>" +
- "<h2 id='qunit-banner'></h2>" +
- "<div id='qunit-testrunner-toolbar'></div>" +
- "<h2 id='qunit-userAgent'></h2>" +
- "<ol id='qunit-tests'></ol>";
- }
-
- tests = id( "qunit-tests" );
- banner = id( "qunit-banner" );
- result = id( "qunit-testresult" );
-
- if ( tests ) {
- tests.innerHTML = "";
- }
-
- if ( banner ) {
- banner.className = "";
- }
-
- if ( result ) {
- result.parentNode.removeChild( result );
- }
-
- if ( tests ) {
- result = document.createElement( "p" );
- result.id = "qunit-testresult";
- result.className = "result";
- tests.parentNode.insertBefore( result, tests );
- result.innerHTML = "Running...<br/>&nbsp;";
- }
- },
-
- // Resets the test setup. Useful for tests that modify the DOM.
- // If jQuery is available, uses jQuery's html(), otherwise just innerHTML.
- reset: function() {
- var fixture;
-
- if ( window.jQuery ) {
- jQuery( "#qunit-fixture" ).html( config.fixture );
- } else {
- fixture = id( "qunit-fixture" );
- if ( fixture ) {
- fixture.innerHTML = config.fixture;
- }
- }
- },
-
- // Trigger an event on an element.
- // @example triggerEvent( document.body, "click" );
- triggerEvent: function( elem, type, event ) {
- if ( document.createEvent ) {
- event = document.createEvent( "MouseEvents" );
- event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
- 0, 0, 0, 0, 0, false, false, false, false, 0, null);
-
- elem.dispatchEvent( event );
- } else if ( elem.fireEvent ) {
- elem.fireEvent( "on" + type );
- }
- },
-
- // Safe object type checking
- is: function( type, obj ) {
- return QUnit.objectType( obj ) == type;
- },
-
- objectType: function( obj ) {
- if ( typeof obj === "undefined" ) {
- return "undefined";
- // consider: typeof null === object
- }
- if ( obj === null ) {
- return "null";
- }
-
- var type = toString.call( obj ).match(/^\[object\s(.*)\]$/)[1] || "";
-
- switch ( type ) {
- case "Number":
- if ( isNaN(obj) ) {
- return "nan";
- }
- return "number";
- case "String":
- case "Boolean":
- case "Array":
- case "Date":
- case "RegExp":
- case "Function":
- return type.toLowerCase();
- }
- if ( typeof obj === "object" ) {
- return "object";
- }
- return undefined;
- },
-
- push: function( result, actual, expected, message ) {
- if ( !config.current ) {
- throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
- }
-
- var output, source,
- details = {
- result: result,
- message: message,
- actual: actual,
- expected: expected
- };
-
- message = escapeInnerText( message ) || ( result ? "okay" : "failed" );
- message = "<span class='test-message'>" + message + "</span>";
- output = message;
-
- if ( !result ) {
- expected = escapeInnerText( QUnit.jsDump.parse(expected) );
- actual = escapeInnerText( QUnit.jsDump.parse(actual) );
- output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
-
- if ( actual != expected ) {
- output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
- output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
- }
-
- source = sourceFromStacktrace();
-
- if ( source ) {
- details.source = source;
- output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr>";
- }
-
- output += "</table>";
- }
-
- runLoggingCallbacks( "log", QUnit, details );
-
- config.current.assertions.push({
- result: !!result,
- message: output
- });
- },
-
- pushFailure: function( message, source ) {
- if ( !config.current ) {
- throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
- }
-
- var output,
- details = {
- result: false,
- message: message
- };
-
- message = escapeInnerText(message ) || "error";
- message = "<span class='test-message'>" + message + "</span>";
- output = message;
-
- if ( source ) {
- details.source = source;
- output += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr></table>";
- }
-
- runLoggingCallbacks( "log", QUnit, details );
-
- config.current.assertions.push({
- result: false,
- message: output
- });
- },
-
- url: function( params ) {
- params = extend( extend( {}, QUnit.urlParams ), params );
- var key,
- querystring = "?";
-
- for ( key in params ) {
- if ( !hasOwn.call( params, key ) ) {
- continue;
- }
- querystring += encodeURIComponent( key ) + "=" +
- encodeURIComponent( params[ key ] ) + "&";
- }
- return window.location.pathname + querystring.slice( 0, -1 );
- },
-
- extend: extend,
- id: id,
- addEvent: addEvent
- // load, equiv, jsDump, diff: Attached later
-});
-
-/**
- * @deprecated: Created for backwards compatibility with test runner that set the hook function
- * into QUnit.{hook}, instead of invoking it and passing the hook function.
- * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
- * Doing this allows us to tell if the following methods have been overwritten on the actual
- * QUnit object.
- */
-extend( QUnit.constructor.prototype, {
-
- // Logging callbacks; all receive a single argument with the listed properties
- // run test/logs.html for any related changes
- begin: registerLoggingCallback( "begin" ),
-
- // done: { failed, passed, total, runtime }
- done: registerLoggingCallback( "done" ),
-
- // log: { result, actual, expected, message }
- log: registerLoggingCallback( "log" ),
-
- // testStart: { name }
- testStart: registerLoggingCallback( "testStart" ),
-
- // testDone: { name, failed, passed, total }
- testDone: registerLoggingCallback( "testDone" ),
-
- // moduleStart: { name }
- moduleStart: registerLoggingCallback( "moduleStart" ),
-
- // moduleDone: { name, failed, passed, total }
- moduleDone: registerLoggingCallback( "moduleDone" )
-});
-
-if ( typeof document === "undefined" || document.readyState === "complete" ) {
- config.autorun = true;
-}
-
-QUnit.load = function() {
- runLoggingCallbacks( "begin", QUnit, {} );
-
- // Initialize the config, saving the execution queue
- var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
- urlConfigHtml = "",
- oldconfig = extend( {}, config );
-
- QUnit.init();
- extend(config, oldconfig);
-
- config.blocking = false;
-
- len = config.urlConfig.length;
-
- for ( i = 0; i < len; i++ ) {
- val = config.urlConfig[i];
- config[val] = QUnit.urlParams[val];
- urlConfigHtml += "<label><input name='" + val + "' type='checkbox'" + ( config[val] ? " checked='checked'" : "" ) + ">" + val + "</label>";
- }
-
- // `userAgent` initialized at top of scope
- userAgent = id( "qunit-userAgent" );
- if ( userAgent ) {
- userAgent.innerHTML = navigator.userAgent;
- }
-
- // `banner` initialized at top of scope
- banner = id( "qunit-header" );
- if ( banner ) {
- banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined }) + "'>" + banner.innerHTML + "</a> " + urlConfigHtml;
- addEvent( banner, "change", function( event ) {
- var params = {};
- params[ event.target.name ] = event.target.checked ? true : undefined;
- window.location = QUnit.url( params );
- });
- }
-
- // `toolbar` initialized at top of scope
- toolbar = id( "qunit-testrunner-toolbar" );
- if ( toolbar ) {
- // `filter` initialized at top of scope
- filter = document.createElement( "input" );
- filter.type = "checkbox";
- filter.id = "qunit-filter-pass";
-
- addEvent( filter, "click", function() {
- var tmp,
- ol = document.getElementById( "qunit-tests" );
-
- if ( filter.checked ) {
- ol.className = ol.className + " hidepass";
- } else {
- tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
- ol.className = tmp.replace( / hidepass /, " " );
- }
- if ( defined.sessionStorage ) {
- if (filter.checked) {
- sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
- } else {
- sessionStorage.removeItem( "qunit-filter-passed-tests" );
- }
- }
- });
-
- if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
- filter.checked = true;
- // `ol` initialized at top of scope
- ol = document.getElementById( "qunit-tests" );
- ol.className = ol.className + " hidepass";
- }
- toolbar.appendChild( filter );
-
- // `label` initialized at top of scope
- label = document.createElement( "label" );
- label.setAttribute( "for", "qunit-filter-pass" );
- label.innerHTML = "Hide passed tests";
- toolbar.appendChild( label );
- }
-
- // `main` initialized at top of scope
- main = id( "qunit-fixture" );
- if ( main ) {
- config.fixture = main.innerHTML;
- }
-
- if ( config.autostart ) {
- QUnit.start();
- }
-};
-
-addEvent( window, "load", QUnit.load );
-
-// `onErrorFnPrev` initialized at top of scope
-// Preserve other handlers
-onErrorFnPrev = window.onerror;
-
-// Cover uncaught exceptions
-// Returning true will surpress the default browser handler,
-// returning false will let it run.
-window.onerror = function ( error, filePath, linerNr ) {
- var ret = false;
- if ( onErrorFnPrev ) {
- ret = onErrorFnPrev( error, filePath, linerNr );
- }
-
- // Treat return value as window.onerror itself does,
- // Only do our handling if not surpressed.
- if ( ret !== true ) {
- if ( QUnit.config.current ) {
- if ( QUnit.config.current.ignoreGlobalErrors ) {
- return true;
- }
- QUnit.pushFailure( error, filePath + ":" + linerNr );
- } else {
- QUnit.test( "global failure", function() {
- QUnit.pushFailure( error, filePath + ":" + linerNr );
- });
- }
- return false;
- }
-
- return ret;
-};
-
-function done() {
- config.autorun = true;
-
- // Log the last module results
- if ( config.currentModule ) {
- runLoggingCallbacks( "moduleDone", QUnit, {
- name: config.currentModule,
- failed: config.moduleStats.bad,
- passed: config.moduleStats.all - config.moduleStats.bad,
- total: config.moduleStats.all
- });
- }
-
- var i, key,
- banner = id( "qunit-banner" ),
- tests = id( "qunit-tests" ),
- runtime = +new Date() - config.started,
- passed = config.stats.all - config.stats.bad,
- html = [
- "Tests completed in ",
- runtime,
- " milliseconds.<br/>",
- "<span class='passed'>",
- passed,
- "</span> tests of <span class='total'>",
- config.stats.all,
- "</span> passed, <span class='failed'>",
- config.stats.bad,
- "</span> failed."
- ].join( "" );
-
- if ( banner ) {
- banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
- }
-
- if ( tests ) {
- id( "qunit-testresult" ).innerHTML = html;
- }
-
- if ( config.altertitle && typeof document !== "undefined" && document.title ) {
- // show ✖ for good, ✔ for bad suite result in title
- // use escape sequences in case file gets loaded with non-utf-8-charset
- document.title = [
- ( config.stats.bad ? "\u2716" : "\u2714" ),
- document.title.replace( /^[\u2714\u2716] /i, "" )
- ].join( " " );
- }
-
- // clear own sessionStorage items if all tests passed
- if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
- // `key` & `i` initialized at top of scope
- for ( i = 0; i < sessionStorage.length; i++ ) {
- key = sessionStorage.key( i++ );
- if ( key.indexOf( "qunit-test-" ) === 0 ) {
- sessionStorage.removeItem( key );
- }
- }
- }
-
- runLoggingCallbacks( "done", QUnit, {
- failed: config.stats.bad,
- passed: passed,
- total: config.stats.all,
- runtime: runtime
- });
-}
-
-/** @return Boolean: true if this test should be ran */
-function validTest( test ) {
- var include,
- filter = config.filter && config.filter.toLowerCase(),
- module = config.module,
- fullName = (test.module + ": " + test.testName).toLowerCase();
-
- if ( config.testNumber ) {
- return test.testNumber === config.testNumber;
- }
-
- if ( module && test.module !== module ) {
- return false;
- }
-
- if ( !filter ) {
- return true;
- }
-
- include = filter.charAt( 0 ) !== "!";
- if ( !include ) {
- filter = filter.slice( 1 );
- }
-
- // If the filter matches, we need to honour include
- if ( fullName.indexOf( filter ) !== -1 ) {
- return include;
- }
-
- // Otherwise, do the opposite
- return !include;
-}
-
-// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
-// Later Safari and IE10 are supposed to support error.stack as well
-// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
-function extractStacktrace( e, offset ) {
- offset = offset === undefined ? 3 : offset;
-
- var stack, include, i, regex;
-
- if ( e.stacktrace ) {
- // Opera
- return e.stacktrace.split( "\n" )[ offset + 3 ];
- } else if ( e.stack ) {
- // Firefox, Chrome
- stack = e.stack.split( "\n" );
- if (/^error$/i.test( stack[0] ) ) {
- stack.shift();
- }
- if ( fileName ) {
- include = [];
- for ( i = offset; i < stack.length; i++ ) {
- if ( stack[ i ].indexOf( fileName ) != -1 ) {
- break;
- }
- include.push( stack[ i ] );
- }
- if ( include.length ) {
- return include.join( "\n" );
- }
- }
- return stack[ offset ];
- } else if ( e.sourceURL ) {
- // Safari, PhantomJS
- // hopefully one day Safari provides actual stacktraces
- // exclude useless self-reference for generated Error objects
- if ( /qunit.js$/.test( e.sourceURL ) ) {
- return;
- }
- // for actual exceptions, this is useful
- return e.sourceURL + ":" + e.line;
- }
-}
-function sourceFromStacktrace( offset ) {
- try {
- throw new Error();
- } catch ( e ) {
- return extractStacktrace( e, offset );
- }
-}
-
-function escapeInnerText( s ) {
- if ( !s ) {
- return "";
- }
- s = s + "";
- return s.replace( /[\&<>]/g, function( s ) {
- switch( s ) {
- case "&": return "&amp;";
- case "<": return "&lt;";
- case ">": return "&gt;";
- default: return s;
- }
- });
-}
-
-function synchronize( callback, last ) {
- config.queue.push( callback );
-
- if ( config.autorun && !config.blocking ) {
- process( last );
- }
-}
-
-function process( last ) {
- function next() {
- process( last );
- }
- var start = new Date().getTime();
- config.depth = config.depth ? config.depth + 1 : 1;
-
- while ( config.queue.length && !config.blocking ) {
- if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
- config.queue.shift()();
- } else {
- window.setTimeout( next, 13 );
- break;
- }
- }
- config.depth--;
- if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
- done();
- }
-}
-
-function saveGlobal() {
- config.pollution = [];
-
- if ( config.noglobals ) {
- for ( var key in window ) {
- // in Opera sometimes DOM element ids show up here, ignore them
- if ( !hasOwn.call( window, key ) || /^qunit-test-output/.test( key ) ) {
- continue;
- }
- config.pollution.push( key );
- }
- }
-}
-
-function checkPollution( name ) {
- var newGlobals,
- deletedGlobals,
- old = config.pollution;
-
- saveGlobal();
-
- newGlobals = diff( config.pollution, old );
- if ( newGlobals.length > 0 ) {
- QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
- }
-
- deletedGlobals = diff( old, config.pollution );
- if ( deletedGlobals.length > 0 ) {
- QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
- }
-}
-
-// returns a new Array with the elements that are in a but not in b
-function diff( a, b ) {
- var i, j,
- result = a.slice();
-
- for ( i = 0; i < result.length; i++ ) {
- for ( j = 0; j < b.length; j++ ) {
- if ( result[i] === b[j] ) {
- result.splice( i, 1 );
- i--;
- break;
- }
- }
- }
- return result;
-}
-
-function extend( a, b ) {
- for ( var prop in b ) {
- if ( b[ prop ] === undefined ) {
- delete a[ prop ];
-
- // Avoid "Member not found" error in IE8 caused by setting window.constructor
- } else if ( prop !== "constructor" || a !== window ) {
- a[ prop ] = b[ prop ];
- }
- }
-
- return a;
-}
-
-function addEvent( elem, type, fn ) {
- if ( elem.addEventListener ) {
- elem.addEventListener( type, fn, false );
- } else if ( elem.attachEvent ) {
- elem.attachEvent( "on" + type, fn );
- } else {
- fn();
- }
-}
-
-function id( name ) {
- return !!( typeof document !== "undefined" && document && document.getElementById ) &&
- document.getElementById( name );
-}
-
-function registerLoggingCallback( key ) {
- return function( callback ) {
- config[key].push( callback );
- };
-}
-
-// Supports deprecated method of completely overwriting logging callbacks
-function runLoggingCallbacks( key, scope, args ) {
- //debugger;
- var i, callbacks;
- if ( QUnit.hasOwnProperty( key ) ) {
- QUnit[ key ].call(scope, args );
- } else {
- callbacks = config[ key ];
- for ( i = 0; i < callbacks.length; i++ ) {
- callbacks[ i ].call( scope, args );
- }
- }
-}
-
-// Test for equality any JavaScript type.
-// Author: Philippe Rathé <prathe@gmail.com>
-QUnit.equiv = (function() {
-
- // Call the o related callback with the given arguments.
- function bindCallbacks( o, callbacks, args ) {
- var prop = QUnit.objectType( o );
- if ( prop ) {
- if ( QUnit.objectType( callbacks[ prop ] ) === "function" ) {
- return callbacks[ prop ].apply( callbacks, args );
- } else {
- return callbacks[ prop ]; // or undefined
- }
- }
- }
-
- // the real equiv function
- var innerEquiv,
- // stack to decide between skip/abort functions
- callers = [],
- // stack to avoiding loops from circular referencing
- parents = [],
-
- getProto = Object.getPrototypeOf || function ( obj ) {
- return obj.__proto__;
- },
- callbacks = (function () {
-
- // for string, boolean, number and null
- function useStrictEquality( b, a ) {
- if ( b instanceof a.constructor || a instanceof b.constructor ) {
- // to catch short annotaion VS 'new' annotation of a
- // declaration
- // e.g. var i = 1;
- // var j = new Number(1);
- return a == b;
- } else {
- return a === b;
- }
- }
-
- return {
- "string": useStrictEquality,
- "boolean": useStrictEquality,
- "number": useStrictEquality,
- "null": useStrictEquality,
- "undefined": useStrictEquality,
-
- "nan": function( b ) {
- return isNaN( b );
- },
-
- "date": function( b, a ) {
- return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
- },
-
- "regexp": function( b, a ) {
- return QUnit.objectType( b ) === "regexp" &&
- // the regex itself
- a.source === b.source &&
- // and its modifers
- a.global === b.global &&
- // (gmi) ...
- a.ignoreCase === b.ignoreCase &&
- a.multiline === b.multiline;
- },
-
- // - skip when the property is a method of an instance (OOP)
- // - abort otherwise,
- // initial === would have catch identical references anyway
- "function": function() {
- var caller = callers[callers.length - 1];
- return caller !== Object && typeof caller !== "undefined";
- },
-
- "array": function( b, a ) {
- var i, j, len, loop;
-
- // b could be an object literal here
- if ( QUnit.objectType( b ) !== "array" ) {
- return false;
- }
-
- len = a.length;
- if ( len !== b.length ) {
- // safe and faster
- return false;
- }
-
- // track reference to avoid circular references
- parents.push( a );
- for ( i = 0; i < len; i++ ) {
- loop = false;
- for ( j = 0; j < parents.length; j++ ) {
- if ( parents[j] === a[i] ) {
- loop = true;// dont rewalk array
- }
- }
- if ( !loop && !innerEquiv(a[i], b[i]) ) {
- parents.pop();
- return false;
- }
- }
- parents.pop();
- return true;
- },
-
- "object": function( b, a ) {
- var i, j, loop,
- // Default to true
- eq = true,
- aProperties = [],
- bProperties = [];
-
- // comparing constructors is more strict than using
- // instanceof
- if ( a.constructor !== b.constructor ) {
- // Allow objects with no prototype to be equivalent to
- // objects with Object as their constructor.
- if ( !(( getProto(a) === null && getProto(b) === Object.prototype ) ||
- ( getProto(b) === null && getProto(a) === Object.prototype ) ) ) {
- return false;
- }
- }
-
- // stack constructor before traversing properties
- callers.push( a.constructor );
- // track reference to avoid circular references
- parents.push( a );
-
- for ( i in a ) { // be strict: don't ensures hasOwnProperty
- // and go deep
- loop = false;
- for ( j = 0; j < parents.length; j++ ) {
- if ( parents[j] === a[i] ) {
- // don't go down the same path twice
- loop = true;
- }
- }
- aProperties.push(i); // collect a's properties
-
- if (!loop && !innerEquiv( a[i], b[i] ) ) {
- eq = false;
- break;
- }
- }
-
- callers.pop(); // unstack, we are done
- parents.pop();
-
- for ( i in b ) {
- bProperties.push( i ); // collect b's properties
- }
-
- // Ensures identical properties name
- return eq && innerEquiv( aProperties.sort(), bProperties.sort() );
- }
- };
- }());
-
- innerEquiv = function() { // can take multiple arguments
- var args = [].slice.apply( arguments );
- if ( args.length < 2 ) {
- return true; // end transition
- }
-
- return (function( a, b ) {
- if ( a === b ) {
- return true; // catch the most you can
- } else if ( a === null || b === null || typeof a === "undefined" ||
- typeof b === "undefined" ||
- QUnit.objectType(a) !== QUnit.objectType(b) ) {
- return false; // don't lose time with error prone cases
- } else {
- return bindCallbacks(a, callbacks, [ b, a ]);
- }
-
- // apply transition with (1..n) arguments
- }( args[0], args[1] ) && arguments.callee.apply( this, args.splice(1, args.length - 1 )) );
- };
-
- return innerEquiv;
-}());
-
-/**
- * jsDump Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com |
- * http://flesler.blogspot.com Licensed under BSD
- * (http://www.opensource.org/licenses/bsd-license.php) Date: 5/15/2008
- *
- * @projectDescription Advanced and extensible data dumping for Javascript.
- * @version 1.0.0
- * @author Ariel Flesler
- * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
- */
-QUnit.jsDump = (function() {
- function quote( str ) {
- return '"' + str.toString().replace( /"/g, '\\"' ) + '"';
- }
- function literal( o ) {
- return o + "";
- }
- function join( pre, arr, post ) {
- var s = jsDump.separator(),
- base = jsDump.indent(),
- inner = jsDump.indent(1);
- if ( arr.join ) {
- arr = arr.join( "," + s + inner );
- }
- if ( !arr ) {
- return pre + post;
- }
- return [ pre, inner + arr, base + post ].join(s);
- }
- function array( arr, stack ) {
- var i = arr.length, ret = new Array(i);
- this.up();
- while ( i-- ) {
- ret[i] = this.parse( arr[i] , undefined , stack);
- }
- this.down();
- return join( "[", ret, "]" );
- }
-
- var reName = /^function (\w+)/,
- jsDump = {
- parse: function( obj, type, stack ) { //type is used mostly internally, you can fix a (custom)type in advance
- stack = stack || [ ];
- var inStack, res,
- parser = this.parsers[ type || this.typeOf(obj) ];
-
- type = typeof parser;
- inStack = inArray( obj, stack );
-
- if ( inStack != -1 ) {
- return "recursion(" + (inStack - stack.length) + ")";
- }
- //else
- if ( type == "function" ) {
- stack.push( obj );
- res = parser.call( this, obj, stack );
- stack.pop();
- return res;
- }
- // else
- return ( type == "string" ) ? parser : this.parsers.error;
- },
- typeOf: function( obj ) {
- var type;
- if ( obj === null ) {
- type = "null";
- } else if ( typeof obj === "undefined" ) {
- type = "undefined";
- } else if ( QUnit.is( "regexp", obj) ) {
- type = "regexp";
- } else if ( QUnit.is( "date", obj) ) {
- type = "date";
- } else if ( QUnit.is( "function", obj) ) {
- type = "function";
- } else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) {
- type = "window";
- } else if ( obj.nodeType === 9 ) {
- type = "document";
- } else if ( obj.nodeType ) {
- type = "node";
- } else if (
- // native arrays
- toString.call( obj ) === "[object Array]" ||
- // NodeList objects
- ( typeof obj.length === "number" && typeof obj.item !== "undefined" && ( obj.length ? obj.item(0) === obj[0] : ( obj.item( 0 ) === null && typeof obj[0] === "undefined" ) ) )
- ) {
- type = "array";
- } else {
- type = typeof obj;
- }
- return type;
- },
- separator: function() {
- return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? "&nbsp;" : " ";
- },
- indent: function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
- if ( !this.multiline ) {
- return "";
- }
- var chr = this.indentChar;
- if ( this.HTML ) {
- chr = chr.replace( /\t/g, " " ).replace( / /g, "&nbsp;" );
- }
- return new Array( this._depth_ + (extra||0) ).join(chr);
- },
- up: function( a ) {
- this._depth_ += a || 1;
- },
- down: function( a ) {
- this._depth_ -= a || 1;
- },
- setParser: function( name, parser ) {
- this.parsers[name] = parser;
- },
- // The next 3 are exposed so you can use them
- quote: quote,
- literal: literal,
- join: join,
- //
- _depth_: 1,
- // This is the list of parsers, to modify them, use jsDump.setParser
- parsers: {
- window: "[Window]",
- document: "[Document]",
- error: "[ERROR]", //when no parser is found, shouldn"t happen
- unknown: "[Unknown]",
- "null": "null",
- "undefined": "undefined",
- "function": function( fn ) {
- var ret = "function",
- name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];//functions never have name in IE
-
- if ( name ) {
- ret += " " + name;
- }
- ret += "( ";
-
- ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" );
- return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" );
- },
- array: array,
- nodelist: array,
- "arguments": array,
- object: function( map, stack ) {
- var ret = [ ], keys, key, val, i;
- QUnit.jsDump.up();
- if ( Object.keys ) {
- keys = Object.keys( map );
- } else {
- keys = [];
- for ( key in map ) {
- keys.push( key );
- }
- }
- keys.sort();
- for ( i = 0; i < keys.length; i++ ) {
- key = keys[ i ];
- val = map[ key ];
- ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) );
- }
- QUnit.jsDump.down();
- return join( "{", ret, "}" );
- },
- node: function( node ) {
- var a, val,
- open = QUnit.jsDump.HTML ? "&lt;" : "<",
- close = QUnit.jsDump.HTML ? "&gt;" : ">",
- tag = node.nodeName.toLowerCase(),
- ret = open + tag;
-
- for ( a in QUnit.jsDump.DOMAttrs ) {
- val = node[ QUnit.jsDump.DOMAttrs[a] ];
- if ( val ) {
- ret += " " + a + "=" + QUnit.jsDump.parse( val, "attribute" );
- }
- }
- return ret + close + open + "/" + tag + close;
- },
- functionArgs: function( fn ) {//function calls it internally, it's the arguments part of the function
- var args,
- l = fn.length;
-
- if ( !l ) {
- return "";
- }
-
- args = new Array(l);
- while ( l-- ) {
- args[l] = String.fromCharCode(97+l);//97 is 'a'
- }
- return " " + args.join( ", " ) + " ";
- },
- key: quote, //object calls it internally, the key part of an item in a map
- functionCode: "[code]", //function calls it internally, it's the content of the function
- attribute: quote, //node calls it internally, it's an html attribute value
- string: quote,
- date: quote,
- regexp: literal, //regex
- number: literal,
- "boolean": literal
- },
- DOMAttrs: {
- //attributes to dump from nodes, name=>realName
- id: "id",
- name: "name",
- "class": "className"
- },
- HTML: false,//if true, entities are escaped ( <, >, \t, space and \n )
- indentChar: " ",//indentation unit
- multiline: true //if true, items in a collection, are separated by a \n, else just a space.
- };
-
- return jsDump;
-}());
-
-// from Sizzle.js
-function getText( elems ) {
- var i, elem,
- ret = "";
-
- for ( i = 0; elems[i]; i++ ) {
- elem = elems[i];
-
- // Get the text from text nodes and CDATA nodes
- if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
- ret += elem.nodeValue;
-
- // Traverse everything else, except comment nodes
- } else if ( elem.nodeType !== 8 ) {
- ret += getText( elem.childNodes );
- }
- }
-
- return ret;
-}
-
-// from jquery.js
-function inArray( elem, array ) {
- if ( array.indexOf ) {
- return array.indexOf( elem );
- }
-
- for ( var i = 0, length = array.length; i < length; i++ ) {
- if ( array[ i ] === elem ) {
- return i;
- }
- }
-
- return -1;
-}
-
-/*
- * Javascript Diff Algorithm
- * By John Resig (http://ejohn.org/)
- * Modified by Chu Alan "sprite"
- *
- * Released under the MIT license.
- *
- * More Info:
- * http://ejohn.org/projects/javascript-diff-algorithm/
- *
- * Usage: QUnit.diff(expected, actual)
- *
- * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
- */
-QUnit.diff = (function() {
- function diff( o, n ) {
- var i,
- ns = {},
- os = {};
-
- for ( i = 0; i < n.length; i++ ) {
- if ( ns[ n[i] ] == null ) {
- ns[ n[i] ] = {
- rows: [],
- o: null
- };
- }
- ns[ n[i] ].rows.push( i );
- }
-
- for ( i = 0; i < o.length; i++ ) {
- if ( os[ o[i] ] == null ) {
- os[ o[i] ] = {
- rows: [],
- n: null
- };
- }
- os[ o[i] ].rows.push( i );
- }
-
- for ( i in ns ) {
- if ( !hasOwn.call( ns, i ) ) {
- continue;
- }
- if ( ns[i].rows.length == 1 && typeof os[i] != "undefined" && os[i].rows.length == 1 ) {
- n[ ns[i].rows[0] ] = {
- text: n[ ns[i].rows[0] ],
- row: os[i].rows[0]
- };
- o[ os[i].rows[0] ] = {
- text: o[ os[i].rows[0] ],
- row: ns[i].rows[0]
- };
- }
- }
-
- for ( i = 0; i < n.length - 1; i++ ) {
- if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
- n[ i + 1 ] == o[ n[i].row + 1 ] ) {
-
- n[ i + 1 ] = {
- text: n[ i + 1 ],
- row: n[i].row + 1
- };
- o[ n[i].row + 1 ] = {
- text: o[ n[i].row + 1 ],
- row: i + 1
- };
- }
- }
-
- for ( i = n.length - 1; i > 0; i-- ) {
- if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
- n[ i - 1 ] == o[ n[i].row - 1 ]) {
-
- n[ i - 1 ] = {
- text: n[ i - 1 ],
- row: n[i].row - 1
- };
- o[ n[i].row - 1 ] = {
- text: o[ n[i].row - 1 ],
- row: i - 1
- };
- }
- }
-
- return {
- o: o,
- n: n
- };
- }
-
- return function( o, n ) {
- o = o.replace( /\s+$/, "" );
- n = n.replace( /\s+$/, "" );
-
- var i, pre,
- str = "",
- out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ),
- oSpace = o.match(/\s+/g),
- nSpace = n.match(/\s+/g);
-
- if ( oSpace == null ) {
- oSpace = [ " " ];
- }
- else {
- oSpace.push( " " );
- }
-
- if ( nSpace == null ) {
- nSpace = [ " " ];
- }
- else {
- nSpace.push( " " );
- }
-
- if ( out.n.length === 0 ) {
- for ( i = 0; i < out.o.length; i++ ) {
- str += "<del>" + out.o[i] + oSpace[i] + "</del>";
- }
- }
- else {
- if ( out.n[0].text == null ) {
- for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) {
- str += "<del>" + out.o[n] + oSpace[n] + "</del>";
- }
- }
-
- for ( i = 0; i < out.n.length; i++ ) {
- if (out.n[i].text == null) {
- str += "<ins>" + out.n[i] + nSpace[i] + "</ins>";
- }
- else {
- // `pre` initialized at top of scope
- pre = "";
-
- for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) {
- pre += "<del>" + out.o[n] + oSpace[n] + "</del>";
- }
- str += " " + out.n[i].text + nSpace[i] + pre;
- }
- }
- }
-
- return str;
- };
-}());
-
-// for CommonJS enviroments, export everything
-if ( typeof exports !== "undefined" ) {
- extend(exports, QUnit);
-}
-
-// get at whatever the global object is, like window in browsers
-}( (function() {return this;}.call()) ));
diff --git a/horizon/static/horizon/lib/spin.jquery.js b/horizon/static/horizon/lib/spin.jquery.js
deleted file mode 100644
index 14975d0e..00000000
--- a/horizon/static/horizon/lib/spin.jquery.js
+++ /dev/null
@@ -1,17 +0,0 @@
-// jQuery add-on for allowing spin.js to act on jQuery elements directly.
-
-$.fn.spin = function(opts) {
- this.each(function() {
- var $this = $(this),
- data = $this.data();
-
- if (data.spinner) {
- data.spinner.stop();
- delete data.spinner;
- }
- if (opts !== false) {
- data.spinner = new Spinner($.extend({color: $this.css('color')}, opts)).spin(this);
- }
- });
- return this;
-};
diff --git a/horizon/static/horizon/lib/spin.js b/horizon/static/horizon/lib/spin.js
deleted file mode 100644
index c38b40e2..00000000
--- a/horizon/static/horizon/lib/spin.js
+++ /dev/null
@@ -1,2 +0,0 @@
-//fgnass.github.com/spin.js#v1.2.5
-(function(a,b,c){function g(a,c){var d=b.createElement(a||"div"),e;for(e in c)d[e]=c[e];return d}function h(a){for(var b=1,c=arguments.length;b<c;b++)a.appendChild(arguments[b]);return a}function j(a,b,c,d){var g=["opacity",b,~~(a*100),c,d].join("-"),h=.01+c/d*100,j=Math.max(1-(1-a)/b*(100-h),a),k=f.substring(0,f.indexOf("Animation")).toLowerCase(),l=k&&"-"+k+"-"||"";return e[g]||(i.insertRule("@"+l+"keyframes "+g+"{"+"0%{opacity:"+j+"}"+h+"%{opacity:"+a+"}"+(h+.01)+"%{opacity:1}"+(h+b)%100+"%{opacity:"+a+"}"+"100%{opacity:"+j+"}"+"}",0),e[g]=1),g}function k(a,b){var e=a.style,f,g;if(e[b]!==c)return b;b=b.charAt(0).toUpperCase()+b.slice(1);for(g=0;g<d.length;g++){f=d[g]+b;if(e[f]!==c)return f}}function l(a,b){for(var c in b)a.style[k(a,c)||c]=b[c];return a}function m(a){for(var b=1;b<arguments.length;b++){var d=arguments[b];for(var e in d)a[e]===c&&(a[e]=d[e])}return a}function n(a){var b={x:a.offsetLeft,y:a.offsetTop};while(a=a.offsetParent)b.x+=a.offsetLeft,b.y+=a.offsetTop;return b}var d=["webkit","Moz","ms","O"],e={},f,i=function(){var a=g("style");return h(b.getElementsByTagName("head")[0],a),a.sheet||a.styleSheet}(),o={lines:12,length:7,width:5,radius:10,rotate:0,color:"#000",speed:1,trail:100,opacity:.25,fps:20,zIndex:2e9,className:"spinner",top:"auto",left:"auto"},p=function q(a){if(!this.spin)return new q(a);this.opts=m(a||{},q.defaults,o)};p.defaults={},m(p.prototype,{spin:function(a){this.stop();var b=this,c=b.opts,d=b.el=l(g(0,{className:c.className}),{position:"relative",zIndex:c.zIndex}),e=c.radius+c.length+c.width,h,i;a&&(a.insertBefore(d,a.firstChild||null),i=n(a),h=n(d),l(d,{left:(c.left=="auto"?i.x-h.x+(a.offsetWidth>>1):c.left+e)+"px",top:(c.top=="auto"?i.y-h.y+(a.offsetHeight>>1):c.top+e)+"px"})),d.setAttribute("aria-role","progressbar"),b.lines(d,b.opts);if(!f){var j=0,k=c.fps,m=k/c.speed,o=(1-c.opacity)/(m*c.trail/100),p=m/c.lines;!function q(){j++;for(var a=c.lines;a;a--){var e=Math.max(1-(j+a*p)%m*o,c.opacity);b.opacity(d,c.lines-a,e,c)}b.timeout=b.el&&setTimeout(q,~~(1e3/k))}()}return b},stop:function(){var a=this.el;return a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=c),this},lines:function(a,b){function e(a,d){return l(g(),{position:"absolute",width:b.length+b.width+"px",height:b.width+"px",background:a,boxShadow:d,transformOrigin:"left",transform:"rotate("+~~(360/b.lines*c+b.rotate)+"deg) translate("+b.radius+"px"+",0)",borderRadius:(b.width>>1)+"px"})}var c=0,d;for(;c<b.lines;c++)d=l(g(),{position:"absolute",top:1+~(b.width/2)+"px",transform:b.hwaccel?"translate3d(0,0,0)":"",opacity:b.opacity,animation:f&&j(b.opacity,b.trail,c,b.lines)+" "+1/b.speed+"s linear infinite"}),b.shadow&&h(d,l(e("#000","0 0 4px #000"),{top:"2px"})),h(a,h(d,e(b.color,"0 0 1px rgba(0,0,0,.1)")));return a},opacity:function(a,b,c){b<a.childNodes.length&&(a.childNodes[b].style.opacity=c)}}),!function(){function a(a,b){return g("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',b)}var b=l(g("group"),{behavior:"url(#default#VML)"});!k(b,"transform")&&b.adj?(i.addRule(".spin-vml","behavior:url(#default#VML)"),p.prototype.lines=function(b,c){function f(){return l(a("group",{coordsize:e+" "+e,coordorigin:-d+" "+ -d}),{width:e,height:e})}function k(b,e,g){h(i,h(l(f(),{rotation:360/c.lines*b+"deg",left:~~e}),h(l(a("roundrect",{arcsize:1}),{width:d,height:c.width,left:c.radius,top:-c.width>>1,filter:g}),a("fill",{color:c.color,opacity:c.opacity}),a("stroke",{opacity:0}))))}var d=c.length+c.width,e=2*d,g=-(c.width+c.length)*2+"px",i=l(f(),{position:"absolute",top:g,left:g}),j;if(c.shadow)for(j=1;j<=c.lines;j++)k(j,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(j=1;j<=c.lines;j++)k(j);return h(b,i)},p.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d<e.childNodes.length&&(e=e.childNodes[b+d],e=e&&e.firstChild,e=e&&e.firstChild,e&&(e.opacity=c))}):f=k(b,"animation")}(),a.Spinner=p})(window,document); \ No newline at end of file
diff --git a/horizon/static/horizon/lib/underscore/underscore-min.js b/horizon/static/horizon/lib/underscore/underscore-min.js
deleted file mode 100644
index 5a0cb3b0..00000000
--- a/horizon/static/horizon/lib/underscore/underscore-min.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Underscore.js 1.3.3
-// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
-// Underscore is freely distributable under the MIT license.
-// Portions of Underscore are inspired or borrowed from Prototype,
-// Oliver Steele's Functional, and John Resig's Micro-Templating.
-// For all details and documentation:
-// http://documentcloud.github.com/underscore
-(function(){function r(a,c,d){if(a===c)return 0!==a||1/a==1/c;if(null==a||null==c)return a===c;a._chain&&(a=a._wrapped);c._chain&&(c=c._wrapped);if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return!1;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:0==a?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
-c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if("object"!=typeof a||"object"!=typeof c)return!1;for(var f=d.length;f--;)if(d[f]==a)return!0;d.push(a);var f=0,g=!0;if("[object Array]"==e){if(f=a.length,g=f==c.length)for(;f--&&(g=f in a==f in c&&r(a[f],c[f],d)););}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return!1;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,h)&&!f--)break;
-g=!f}}d.pop();return g}var s=this,I=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,J=k.unshift,l=p.toString,K=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,L=Object.keys,t=Function.prototype.bind,b=function(a){return new m(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;b.VERSION="1.3.3";var j=b.each=b.forEach=function(a,
-c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===o)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===o)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.map===z)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(A&&
-a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,i){if(f)d=c.call(e,d,a,b,i);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,
-c,b){var e;G(a,function(a,g,h){if(c.call(b,a,g,h)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,b);j(a,function(a,g,h){if(!(e=e&&c.call(b,
-a,g,h)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
-function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0])return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&
-(e={value:a,computed:b})});return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){d=Math.floor(Math.random()*(f+1));b[f]=b[d];b[d]=a});return b};b.sortBy=function(a,c,d){var e=b.isFunction(c)?c:function(a){return a[c]};return b.pluck(b.map(a,function(a,b,c){return{value:a,criteria:e.call(d,a,b,c)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c===void 0?1:d===void 0?-1:c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};
-j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:b.isArray(a)||b.isArguments(a)?i.call(a):a.toArray&&b.isFunction(a.toArray)?a.toArray():b.values(a)};b.size=function(a){return b.isArray(a)?a.length:b.keys(a).length};b.first=b.head=b.take=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,
-0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,
-e=[];a.length<3&&(c=true);b.reduce(d,function(d,g,h){if(c?b.last(d)!==g||!d.length:!b.include(d,g)){d.push(g);e.push(a[h])}return d},[]);return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1),true);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=
-i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d){d=b.sortedIndex(a,c);return a[d]===c?d:-1}if(q&&a.indexOf===q)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(F&&a.lastIndexOf===F)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){if(arguments.length<=
-1){b=a||0;a=0}for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;){g[f++]=a;a=a+d}return g};var H=function(){};b.bind=function(a,c){var d,e;if(a.bind===t&&t)return t.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));H.prototype=a.prototype;var b=new H,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=
-i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(null,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i,j=b.debounce(function(){h=
-g=false},c);return function(){d=this;e=arguments;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);j()},c));g?h=true:i=a.apply(d,e);j();g=true;return i}};b.debounce=function(a,b,d){var e;return function(){var f=this,g=arguments;d&&!e&&a.apply(f,g);clearTimeout(e);e=setTimeout(function(){e=null;d||a.apply(f,g)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));
-return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=L||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&
-c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={};j(b.flatten(i.call(arguments,1)),function(b){b in a&&(c[b]=a[b])});return c};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=
-function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return l.call(a)=="[object Arguments]"};b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFunction=function(a){return l.call(a)=="[object Function]"};
-b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,
-b){return K.call(a,b)};b.noConflict=function(){s._=I;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")};b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){M(c,b[c]=a[c])})};var N=0;b.uniqueId=
-function(a){var b=N++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var u=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},v;for(v in n)n[n[v]]=v;var O=/\\|'|\r|\n|\t|\u2028|\u2029/g,P=/\\(\\|'|r|n|t|u2028|u2029)/g,w=function(a){return a.replace(P,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.defaults(d||{},b.templateSettings);a="__p+='"+a.replace(O,function(a){return"\\"+n[a]}).replace(d.escape||
-u,function(a,b){return"'+\n_.escape("+w(b)+")+\n'"}).replace(d.interpolate||u,function(a,b){return"'+\n("+w(b)+")+\n'"}).replace(d.evaluate||u,function(a,b){return"';\n"+w(b)+"\n;__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");var a="var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n"+a+"return __p;\n",e=new Function(d.variable||"obj","_",a);if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c};
-b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var x=function(a,c){return c?b(a).chain():a},M=function(a,c){m.prototype[a]=function(){var a=i.call(arguments);J.call(a,this._wrapped);return x(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return x(d,
-this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return x(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
diff --git a/horizon/static/horizon/tests/messages.js b/horizon/static/horizon/tests/messages.js
deleted file mode 100644
index f7522424..00000000
--- a/horizon/static/horizon/tests/messages.js
+++ /dev/null
@@ -1,38 +0,0 @@
-horizon.addInitFunction(function () {
- module("Messages (horizon.messages.js)");
-
- test("Basic Alert", function () {
- var message, message2;
- message = horizon.alert("success", "A message!");
- ok(message, "Create a success message.");
- ok(message.hasClass("alert-success"), 'Verify the message has the "alert-success" class.');
- equal($('#main_content .messages .alert').length, 1, "Verify our message was added to the DOM.");
- horizon.clearAllMessages();
- equal($('#main_content .messages .alert').length, 0, "Verify our message was removed.");
- });
-
- test("Multiple Alerts", function () {
- message = horizon.alert("error", "An error!");
- ok(message.hasClass("alert-error"), 'Verify the first message has the "alert-error" class.');
-
- message2 = horizon.alert("success", "Another message");
- equal($('#main_content .messages .alert').length, 2, "Verify two messages have been added to the DOM.");
-
- horizon.clearErrorMessages();
- equal($('#main_content .messages .alert-error').length, 0, "Verify our error message was removed.");
- equal($('#main_content .messages .alert').length, 1, "Verify one message remains.");
- horizon.clearSuccessMessages();
- equal($('#main_content .messages .alert-success').length, 0, "Verify our success message was removed.");
- equal($('#main_content .messages .alert').length, 0, "Verify no messages remain.");
- });
-
- test("Alert With HTML Tag", function () {
- safe_string = "A safe message <a>here</a>!"
- message = horizon.alert("success", safe_string, "safe");
- ok(message, "Create a message with extra tag.");
- ok((message.html().indexOf(safe_string ) != -1), 'Verify the message with HTML tag was not escaped.');
- equal($('#main_content .messages .alert').length, 1, "Verify our message was added to the DOM.");
- horizon.clearAllMessages();
- equal($('#main_content .messages .alert').length, 0, "Verify our message was removed.");
- });
-});
diff --git a/horizon/static/horizon/tests/modals.js b/horizon/static/horizon/tests/modals.js
deleted file mode 100644
index 5d94f3fa..00000000
--- a/horizon/static/horizon/tests/modals.js
+++ /dev/null
@@ -1,22 +0,0 @@
-horizon.addInitFunction(function () {
- module("Modals (horizon.modals.js)");
-
- test("Modal Creation", function () {
- var modal,
- title = "Test Title",
- body = "<p>Test Body</p>",
- confirm = "Test Confirm";
- modal = horizon.modals.create(title, body, confirm);
- ok(modal, "Verify our modal was created.");
-
- modal = $("#modal_wrapper .modal");
- modal.modal();
- equal(modal.length, 1, "Verify our modal was added to the DOM.");
- ok(modal.hasClass("in"), "Verify our modal is not hidden.");
- equal(modal.find("h3").text(), title, "Verify the title was added correctly.");
- equal(modal.find(".modal-body").text().trim(), body, "Verify the body was added correctly.");
- equal(modal.find(".modal-footer .btn-primary").text(), confirm, "Verify the footer confirm button was added correctly.");
- modal.find(".modal-footer .cancel").click();
- ok(!modal.hasClass("in"), "Verify our modal is hidden.");
- });
-});
diff --git a/horizon/static/horizon/tests/tables.js b/horizon/static/horizon/tests/tables.js
deleted file mode 100644
index cbccdd90..00000000
--- a/horizon/static/horizon/tests/tables.js
+++ /dev/null
@@ -1,49 +0,0 @@
-module("Tables (horizon.tables.js)");
-
-test("Row filtering (fixed)", function () {
- var fixture = $("#qunit-fixture");
- var table = fixture.find("#table2");
-
- ok(!table.find(".cat").is(":hidden"), "Filtering cats: cats visible by default");
- ok(table.find(":not(.cat)").is(":hidden"), "Filtering cats: non-cats hidden by default");
-
- $("#button_cats").trigger("click");
- ok(!table.find(".cat").is(":hidden"), "Filtering cats: cats visible");
- ok(table.find(":not(.cat)").is(":hidden"), "Filtering cats: non-cats hidden");
-
- $("#button_dogs").trigger("click");
- ok(!table.find(".dog").is(":hidden"), "Filtering dogs: dogs visible");
- ok(table.find(":not(.dog)").is(":hidden"), "Filtering dogs: non-dogs hidden");
-
- $("#button_big").trigger("click");
- ok(!table.find(".big").is(":hidden"), "Filtering big animals: big visible");
- ok(table.find(":not(.big)").is(":hidden"), "Filtering big animals: non-big hidden");
-});
-
-test("Footer count update", function () {
- var fixture = $("#qunit-fixture");
- var table = fixture.find("#table1");
- var tbody = table.find('tbody');
- var table_count = table.find("span.table_count");
- var rows = tbody.find('tr');
-
- horizon.datatables.update_footer_count(table);
- notEqual(table_count.text().indexOf('4 items'), -1, "Initial count is correct");
-
- // hide rows
- rows.first().hide();
- rows.first().next().hide();
- horizon.datatables.update_footer_count(table);
- notEqual(table_count.text().indexOf('2 items'), -1, "Count correct after hiding two rows");
-
- // show a row
- rows.first().next().show();
- horizon.datatables.update_footer_count(table);
- notEqual(table_count.text().indexOf('3 items'), -1, "Count correct after showing one row");
-
- // add rows
- $('<tr><td>cat3</td></tr>"').appendTo(tbody);
- $('<tr><td>cat4</td></tr>"').appendTo(tbody);
- horizon.datatables.update_footer_count(table);
- notEqual(table_count.text().indexOf('5 items'), -1, "Count correct after adding two rows");
-});
diff --git a/horizon/static/horizon/tests/templates.js b/horizon/static/horizon/tests/templates.js
deleted file mode 100644
index cb6eb6a2..00000000
--- a/horizon/static/horizon/tests/templates.js
+++ /dev/null
@@ -1,7 +0,0 @@
-horizon.addInitFunction(function () {
- module("Client-Side Templating (horizon.templates.js)");
-
- test("Template Compilation", function () {
- ok(_.size(horizon.templates.compiled_templates) > 0, "Compiled templates list should not be empty.");
- });
-});
diff --git a/horizon/tables/__init__.py b/horizon/tables/__init__.py
deleted file mode 100644
index d279db63..00000000
--- a/horizon/tables/__init__.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# Convenience imports for public API components.
-from horizon.tables.actions import Action
-from horizon.tables.actions import BatchAction
-from horizon.tables.actions import DeleteAction
-from horizon.tables.actions import FilterAction
-from horizon.tables.actions import FixedFilterAction
-from horizon.tables.actions import LinkAction
-from horizon.tables.base import Column
-from horizon.tables.base import DataTable
-from horizon.tables.base import Row
-from horizon.tables.views import DataTableView
-from horizon.tables.views import MixedDataTableView
-from horizon.tables.views import MultiTableMixin
-from horizon.tables.views import MultiTableView
-
-assert Action
-assert BatchAction
-assert DeleteAction
-assert LinkAction
-assert FilterAction
-assert FixedFilterAction
-assert DataTable
-assert Column
-assert Row
-assert DataTableView
-assert MultiTableView
-assert MultiTableMixin
-assert MixedDataTableView
diff --git a/horizon/tables/actions.py b/horizon/tables/actions.py
deleted file mode 100644
index b6aa0a4a..00000000
--- a/horizon/tables/actions.py
+++ /dev/null
@@ -1,625 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from collections import defaultdict
-import logging
-import new
-
-from django.conf import settings
-from django.core import urlresolvers
-from django import shortcuts
-from django.utils.functional import Promise
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import messages
-from horizon.utils import functions
-from horizon.utils import html
-
-
-LOG = logging.getLogger(__name__)
-
-# For Bootstrap integration; can be overridden in settings.
-ACTION_CSS_CLASSES = ("btn", "btn-small")
-STRING_SEPARATOR = "__"
-
-
-class BaseAction(html.HTMLElement):
- """ Common base class for all ``Action`` classes. """
- table = None
- handles_multiple = False
- requires_input = False
- preempt = False
-
- def __init__(self, datum=None):
- super(BaseAction, self).__init__()
- self.datum = datum
-
- def data_type_matched(self, datum):
- """ Method to see if the action is allowed for a certain type of data.
- Only affects mixed data type tables.
- """
- if datum:
- action_data_types = getattr(self, "allowed_data_types", [])
- # If the data types of this action is empty, we assume it accepts
- # all kinds of data and this method will return True.
- if action_data_types:
- datum_type = getattr(datum, self.table._meta.data_type_name,
- None)
- if datum_type and (datum_type not in action_data_types):
- return False
- return True
-
- def allowed(self, request, datum):
- """ Determine whether this action is allowed for the current request.
-
- This method is meant to be overridden with more specific checks.
- """
- return True
-
- def _allowed(self, request, datum):
- return self.allowed(request, datum)
-
- def update(self, request, datum):
- """ Allows per-action customization based on current conditions.
-
- This is particularly useful when you wish to create a "toggle"
- action that will be rendered differently based on the value of an
- attribute on the current row's data.
-
- By default this method is a no-op.
- """
- pass
-
- def get_default_classes(self):
- """
- Returns a list of the default classes for the action. Defaults to
- ``["btn", "btn-small"]``.
- """
- return getattr(settings, "ACTION_CSS_CLASSES", ACTION_CSS_CLASSES)
-
- def get_default_attrs(self):
- """
- Returns a list of the default HTML attributes for the action. Defaults
- to returning an ``id`` attribute with the value
- ``{{ table.name }}__action_{{ action.name }}__{{ creation counter }}``.
- """
- if self.datum is not None:
- bits = (self.table.name,
- "row_%s" % self.table.get_object_id(self.datum),
- "action_%s" % self.name)
- else:
- bits = (self.table.name, "action_%s" % self.name)
- return {"id": STRING_SEPARATOR.join(bits)}
-
- def __repr__(self):
- return "<%s: %s>" % (self.__class__.__name__, self.name)
-
-
-class Action(BaseAction):
- """ Represents an action which can be taken on this table's data.
-
- .. attribute:: name
-
- Required. The short name or "slug" representing this
- action. This name should not be changed at runtime.
-
- .. attribute:: verbose_name
-
- A descriptive name used for display purposes. Defaults to the
- value of ``name`` with the first letter of each word capitalized.
-
- .. attribute:: verbose_name_plural
-
- Used like ``verbose_name`` in cases where ``handles_multiple`` is
- ``True``. Defaults to ``verbose_name`` with the letter "s" appended.
-
- .. attribute:: method
-
- The HTTP method for this action. Defaults to ``POST``. Other methods
- may or may not succeed currently.
-
- .. attribute:: requires_input
-
- Boolean value indicating whether or not this action can be taken
- without any additional input (e.g. an object id). Defaults to ``True``.
-
- .. attribute:: preempt
-
- Boolean value indicating whether this action should be evaluated in
- the period after the table is instantiated but before the data has
- been loaded.
-
- This can allow actions which don't need access to the full table data
- to bypass any API calls and processing which would otherwise be
- required to load the table.
-
- .. attribute:: allowed_data_types
-
- A list that contains the allowed data types of the action. If the
- datum's type is in this list, the action will be shown on the row
- for the datum.
-
- Default to be an empty list (``[]``). When set to empty, the action
- will accept any kind of data.
-
- At least one of the following methods must be defined:
-
- .. method:: single(self, data_table, request, object_id)
-
- Handler for a single-object action.
-
- .. method:: multiple(self, data_table, request, object_ids)
-
- Handler for multi-object actions.
-
- .. method:: handle(self, data_table, request, object_ids)
-
- If a single function can work for both single-object and
- multi-object cases then simply providing a ``handle`` function
- will internally route both ``single`` and ``multiple`` requests
- to ``handle`` with the calls from ``single`` being transformed
- into a list containing only the single object id.
- """
- method = "POST"
- requires_input = True
-
- def __init__(self, verbose_name=None, verbose_name_plural=None,
- single_func=None, multiple_func=None, handle_func=None,
- handles_multiple=False, attrs=None, requires_input=True,
- allowed_data_types=[], datum=None):
- super(Action, self).__init__(datum=datum)
- # Priority: constructor, class-defined, fallback
- self.verbose_name = verbose_name or getattr(self, 'verbose_name',
- self.name.title())
- self.verbose_name_plural = verbose_name_plural or \
- getattr(self, 'verbose_name_plural',
- "%ss" % self.verbose_name)
- self.handles_multiple = getattr(self,
- "handles_multiple",
- handles_multiple)
- self.requires_input = getattr(self,
- "requires_input",
- requires_input)
- self.allowed_data_types = getattr(self, "allowed_data_types",
- allowed_data_types)
-
- if attrs:
- self.attrs.update(attrs)
-
- # Don't set these if they're None
- if single_func:
- self.single = single_func
- if multiple_func:
- self.multiple = multiple_func
- if handle_func:
- self.handle = handle_func
-
- # Ensure we have the appropriate methods
- has_handler = hasattr(self, 'handle') and callable(self.handle)
- has_single = hasattr(self, 'single') and callable(self.single)
- has_multiple = hasattr(self, 'multiple') and callable(self.multiple)
-
- if has_handler or has_multiple:
- self.handles_multiple = True
-
- if not has_handler and (not has_single or has_multiple):
- cls_name = self.__class__.__name__
- raise NotImplementedError('You must define either a "handle" '
- 'method or a "single" or "multiple" '
- 'method on %s.' % cls_name)
-
- if not has_single:
- def single(self, data_table, request, object_id):
- return self.handle(data_table, request, [object_id])
- self.single = new.instancemethod(single, self)
-
- if not has_multiple and self.handles_multiple:
- def multiple(self, data_table, request, object_ids):
- return self.handle(data_table, request, object_ids)
- self.multiple = new.instancemethod(multiple, self)
-
- def get_param_name(self):
- """ Returns the full POST parameter name for this action.
-
- Defaults to
- ``{{ table.name }}__{{ action.name }}``.
- """
- return "__".join([self.table.name, self.name])
-
-
-class LinkAction(BaseAction):
- """ A table action which is simply a link rather than a form POST.
-
- .. attribute:: name
-
- Required. The short name or "slug" representing this
- action. This name should not be changed at runtime.
-
- .. attribute:: verbose_name
-
- A string which will be rendered as the link text. (Required)
-
- .. attribute:: url
-
- A string or a callable which resolves to a url to be used as the link
- target. You must either define the ``url`` attribute or override
- the ``get_link_url`` method on the class.
-
- .. attribute:: allowed_data_types
-
- A list that contains the allowed data types of the action. If the
- datum's type is in this list, the action will be shown on the row
- for the datum.
-
- Defaults to be an empty list (``[]``). When set to empty, the action
- will accept any kind of data.
- """
- method = "GET"
- bound_url = None
-
- def __init__(self, verbose_name=None, allowed_data_types=[],
- url=None, attrs=None):
- super(LinkAction, self).__init__()
- self.verbose_name = verbose_name or getattr(self,
- "verbose_name",
- self.name.title())
- self.url = getattr(self, "url", url)
- if not self.verbose_name:
- raise NotImplementedError('A LinkAction object must have a '
- 'verbose_name attribute.')
- self.allowed_data_types = getattr(self, "allowed_data_types",
- allowed_data_types)
- if attrs:
- self.attrs.update(attrs)
-
- def get_link_url(self, datum=None):
- """ Returns the final URL based on the value of ``url``.
-
- If ``url`` is callable it will call the function.
- If not, it will then try to call ``reverse`` on ``url``.
- Failing that, it will simply return the value of ``url`` as-is.
-
- When called for a row action, the current row data object will be
- passed as the first parameter.
- """
- if not self.url:
- raise NotImplementedError('A LinkAction class must have a '
- 'url attribute or define its own '
- 'get_link_url method.')
- if callable(self.url):
- return self.url(datum, **self.kwargs)
- try:
- if datum:
- obj_id = self.table.get_object_id(datum)
- return urlresolvers.reverse(self.url, args=(obj_id,))
- else:
- return urlresolvers.reverse(self.url)
- except urlresolvers.NoReverseMatch as ex:
- LOG.info('No reverse found for "%s": %s' % (self.url, ex))
- return self.url
-
-
-class FilterAction(BaseAction):
- """ A base class representing a filter action for a table.
-
- .. attribute:: name
-
- The short name or "slug" representing this action. Defaults to
- ``"filter"``.
-
- .. attribute:: verbose_name
-
- A descriptive name used for display purposes. Defaults to the
- value of ``name`` with the first letter of each word capitalized.
-
- .. attribute:: param_name
-
- A string representing the name of the request parameter used for the
- search term. Default: ``"q"``.
-
- .. attribute: filter_type
-
- A string representing the type of this filter. Default: ``"query"``.
-
- .. attribute: needs_preloading
-
- If True, the filter function will be called for the initial
- GET request with an empty ``filter_string``, regardless of the
- value of ``method``.
- """
- # TODO(gabriel): The method for a filter action should be a GET,
- # but given the form structure of the table that's currently impossible.
- # At some future date this needs to be reworked to get the filter action
- # separated from the table's POST form.
- method = "POST"
- name = "filter"
- verbose_name = _("Filter")
- filter_type = "query"
- needs_preloading = False
-
- def __init__(self, verbose_name=None, param_name=None):
- super(FilterAction, self).__init__()
- self.verbose_name = verbose_name or self.name
- self.param_name = param_name or 'q'
-
- def get_param_name(self):
- """ Returns the full query parameter name for this action.
-
- Defaults to
- ``{{ table.name }}__{{ action.name }}__{{ action.param_name }}``.
- """
- return "__".join([self.table.name, self.name, self.param_name])
-
- def get_default_classes(self):
- classes = super(FilterAction, self).get_default_classes()
- classes += ("btn-search",)
- return classes
-
- def assign_type_string(self, table, data, type_string):
- for datum in data:
- setattr(datum, table._meta.data_type_name, type_string)
-
- def data_type_filter(self, table, data, filter_string):
- filtered_data = []
- for data_type in table._meta.data_types:
- func_name = "filter_%s_data" % data_type
- filter_func = getattr(self, func_name, None)
- if not filter_func and not callable(filter_func):
- # The check of filter function implementation should happen
- # in the __init__. However, the current workflow of DataTable
- # and actions won't allow it. Need to be fixed in the future.
- cls_name = self.__class__.__name__
- raise NotImplementedError("You must define a %s method "
- "for %s data type in %s." %
- (func_name, data_type, cls_name))
- _data = filter_func(table, data, filter_string)
- self.assign_type_string(table, _data, data_type)
- filtered_data.extend(_data)
- return filtered_data
-
- def filter(self, table, data, filter_string):
- """ Provides the actual filtering logic.
-
- This method must be overridden by subclasses and return
- the filtered data.
- """
- raise NotImplementedError("The filter method has not been "
- "implemented by %s." % self.__class__)
-
-
-class FixedFilterAction(FilterAction):
- """ A filter action with fixed buttons.
- """
- filter_type = 'fixed'
- needs_preloading = True
-
- def __init__(self, *args, **kwargs):
- super(FixedFilterAction, self).__init__(args, kwargs)
- self.fixed_buttons = self.get_fixed_buttons()
- self.filter_string = ''
-
- def filter(self, table, images, filter_string):
- self.filter_string = filter_string
- categories = self.categorize(table, images)
- self.categories = defaultdict(list, categories)
- for button in self.fixed_buttons:
- button['count'] = len(self.categories[button['value']])
- if not filter_string:
- return images
- return self.categories[filter_string]
-
- def get_fixed_buttons(self):
- """Returns a list of dictionaries describing the fixed buttons
- to use for filtering.
-
- Each list item should be a dict with the keys:
- text: Text to display on the button
- icon: Icon class for icon element (inserted before text).
- value: Value returned when the button is clicked.
- This value is passed to ``filter()`` as
- ``filter_string``.
- """
- raise NotImplementedError("The get_fixed_buttons method has "
- "not been implemented by %s." %
- self.__class__)
-
- def categorize(self, table, images):
- """Override to separate images into categories.
-
- Return a dict with a key for the value of each fixed button,
- and a value that is a list of images in that category.
- """
- raise NotImplementedError("The categorize method has not been "
- "implemented by %s." % self.__class__)
-
-
-class BatchAction(Action):
- """ A table action which takes batch action on one or more
- objects. This action should not require user input on a
- per-object basis.
-
- .. attribute:: name
-
- An internal name for this action.
-
- .. attribute:: action_present
-
- String or tuple/list. The display forms of the name.
- Should be a transitive verb, capitalized and translated. ("Delete",
- "Rotate", etc.) If tuple or list - then setting
- self.current_present_action = n will set the current active item
- from the list(action_present[n])
-
- .. attribute:: action_past
-
- String or tuple/list. The past tense of action_present. ("Deleted",
- "Rotated", etc.) If tuple or list - then
- setting self.current_past_action = n will set the current active item
- from the list(action_past[n])
-
- .. attribute:: data_type_singular
-
- A display name for the type of data that receives the
- action. ("Keypair", "Floating IP", etc.)
-
- .. attribute:: data_type_plural
-
- Optional plural word for the type of data being acted
- on. Defaults to appending 's'. Relying on the default is bad
- for translations and should not be done.
-
- .. attribute:: success_url
-
- Optional location to redirect after completion of the delete
- action. Defaults to the current page.
- """
- success_url = None
-
- def __init__(self):
- self.current_present_action = 0
- self.current_past_action = 0
- self.data_type_plural = getattr(self, 'data_type_plural',
- self.data_type_singular + 's')
- # If setting a default name, don't initialise it too early
- self.verbose_name = getattr(self, "verbose_name",
- self._conjugate)
- self.verbose_name_plural = getattr(self, "verbose_name_plural",
- lambda: self._conjugate('plural'))
- # Keep record of successfully handled objects
- self.success_ids = []
- super(BatchAction, self).__init__()
-
- def _allowed(self, request, datum=None):
- # Override the default internal action method to prevent batch
- # actions from appearing on tables with no data.
- if not self.table.data and not datum:
- return False
- return super(BatchAction, self)._allowed(request, datum)
-
- def _conjugate(self, items=None, past=False):
- """
- Builds combinations like 'Delete Object' and 'Deleted
- Objects' based on the number of items and `past` flag.
- """
- action_type = "past" if past else "present"
- action_attr = getattr(self, "action_%s" % action_type)
- if isinstance(action_attr, (basestring, Promise)):
- action = action_attr
- else:
- toggle_selection = getattr(self, "current_%s_action" % action_type)
- action = action_attr[toggle_selection]
- if items is None or len(items) == 1:
- data_type = self.data_type_singular
- else:
- data_type = self.data_type_plural
- return _("%(action)s %(data_type)s") % {'action': action,
- 'data_type': data_type}
-
- def action(self, request, datum_id):
- """
- Required. Accepts a single object id and performs the specific action.
-
- Return values are discarded, errors raised are caught and logged.
- """
- raise NotImplementedError('action() must be defined for '
- 'BatchAction: %s' % self.data_type_singular)
-
- def update(self, request, datum):
- """
- Switches the action verbose name, if needed
- """
- if getattr(self, 'action_present', False):
- self.verbose_name = self._conjugate()
- self.verbose_name_plural = self._conjugate('plural')
-
- def get_success_url(self, request=None):
- """
- Returns the URL to redirect to after a successful action.
- """
- if self.success_url:
- return self.success_url
- return request.get_full_path()
-
- def handle(self, table, request, obj_ids):
- action_success = []
- action_failure = []
- action_not_allowed = []
- for datum_id in obj_ids:
- datum = table.get_object_by_id(datum_id)
- datum_display = table.get_object_display(datum) or _("N/A")
- if not table._filter_action(self, request, datum):
- action_not_allowed.append(datum_display)
- LOG.info('Permission denied to %s: "%s"' %
- (self._conjugate(past=True).lower(), datum_display))
- continue
- try:
- self.action(request, datum_id)
- #Call update to invoke changes if needed
- self.update(request, datum)
- action_success.append(datum_display)
- self.success_ids.append(datum_id)
- LOG.info('%s: "%s"' %
- (self._conjugate(past=True), datum_display))
- except Exception as ex:
- # Handle the exception but silence it since we'll display
- # an aggregate error message later. Otherwise we'd get
- # multiple error messages displayed to the user.
- if getattr(ex, "_safe_message", None):
- ignore = False
- else:
- ignore = True
- action_failure.append(datum_display)
- exceptions.handle(request, ignore=ignore)
-
- # Begin with success message class, downgrade to info if problems.
- success_message_level = messages.success
- if action_not_allowed:
- msg = _('You do not have permission to %(action)s: %(objs)s')
- params = {"action": self._conjugate(action_not_allowed).lower(),
- "objs": functions.lazy_join(", ", action_not_allowed)}
- messages.error(request, msg % params)
- success_message_level = messages.info
- if action_failure:
- msg = _('Unable to %(action)s: %(objs)s')
- params = {"action": self._conjugate(action_failure).lower(),
- "objs": functions.lazy_join(", ", action_failure)}
- messages.error(request, msg % params)
- success_message_level = messages.info
- if action_success:
- msg = _('%(action)s: %(objs)s')
- params = {"action": self._conjugate(action_success, True),
- "objs": functions.lazy_join(", ", action_success)}
- success_message_level(request, msg % params)
-
- return shortcuts.redirect(self.get_success_url(request))
-
-
-class DeleteAction(BatchAction):
- name = "delete"
- action_present = _("Delete")
- action_past = _("Deleted")
-
- def action(self, request, obj_id):
- return self.delete(request, obj_id)
-
- def delete(self, request, obj_id):
- raise NotImplementedError("DeleteAction must define a delete method.")
-
- def get_default_classes(self):
- classes = super(DeleteAction, self).get_default_classes()
- classes += ("btn-danger", "btn-delete")
- return classes
diff --git a/horizon/tables/base.py b/horizon/tables/base.py
deleted file mode 100644
index 7a0edaed..00000000
--- a/horizon/tables/base.py
+++ /dev/null
@@ -1,1396 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import collections
-import copy
-import logging
-from operator import attrgetter
-import sys
-
-from django.conf import settings
-from django.core import urlresolvers
-from django import forms
-from django.http import HttpResponse
-from django import template
-from django.template.defaultfilters import truncatechars
-from django.template.loader import render_to_string
-from django.utils.datastructures import SortedDict
-from django.utils.html import escape
-from django.utils import http
-from django.utils.http import urlencode
-from django.utils.safestring import mark_safe
-from django.utils import termcolors
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import conf
-from horizon import exceptions
-from horizon import messages
-from horizon.tables.actions import FilterAction
-from horizon.tables.actions import LinkAction
-from horizon.utils import html
-
-
-LOG = logging.getLogger(__name__)
-PALETTE = termcolors.PALETTES[termcolors.DEFAULT_PALETTE]
-STRING_SEPARATOR = "__"
-
-
-class Column(html.HTMLElement):
- """ A class which represents a single column in a :class:`.DataTable`.
-
- .. attribute:: transform
-
- A string or callable. If ``transform`` is a string, it should be the
- name of the attribute on the underlying data class which
- should be displayed in this column. If it is a callable, it
- will be passed the current row's data at render-time and should
- return the contents of the cell. Required.
-
- .. attribute:: verbose_name
-
- The name for this column which should be used for display purposes.
- Defaults to the value of ``transform`` with the first letter
- of each word capitalized.
-
- .. attribute:: sortable
-
- Boolean to determine whether this column should be sortable or not.
- Defaults to ``True``.
-
- .. attribute:: hidden
-
- Boolean to determine whether or not this column should be displayed
- when rendering the table. Default: ``False``.
-
- .. attribute:: link
-
- A string or callable which returns a URL which will be wrapped around
- this column's text as a link.
-
- .. attribute:: allowed_data_types
-
- A list of data types for which the link should be created.
- Default is an empty list (``[]``).
-
- When the list is empty and the ``link`` attribute is not None, all the
- rows under this column will be links.
-
- .. attribute:: status
-
- Boolean designating whether or not this column represents a status
- (i.e. "enabled/disabled", "up/down", "active/inactive").
- Default: ``False``.
-
- .. attribute:: status_choices
-
- A tuple of tuples representing the possible data values for the
- status column and their associated boolean equivalent. Positive
- states should equate to ``True``, negative states should equate
- to ``False``, and indeterminate states should be ``None``.
-
- Values are compared in a case-insensitive manner.
-
- Example (these are also the default values)::
-
- status_choices = (
- ('enabled', True),
- ('true', True)
- ('up', True),
- ('active', True),
- ('on', True),
- ('none', None),
- ('unknown', None),
- ('', None),
- ('disabled', False),
- ('down', False),
- ('false', False),
- ('inactive', False),
- ('off', False),
- )
-
- .. attribute:: display_choices
-
- A tuple of tuples representing the possible values to substitute
- the data when displayed in the column cell.
-
- .. attribute:: empty_value
-
- A string or callable to be used for cells which have no data.
- Defaults to the string ``"-"``.
-
- .. attribute:: summation
-
- A string containing the name of a summation method to be used in
- the generation of a summary row for this column. By default the
- options are ``"sum"`` or ``"average"``, which behave as expected.
- Optional.
-
- .. attribute:: filters
-
- A list of functions (often template filters) to be applied to the
- value of the data for this column prior to output. This is effectively
- a shortcut for writing a custom ``transform`` function in simple cases.
-
- .. attribute:: classes
-
- An iterable of CSS classes which should be added to this column.
- Example: ``classes=('foo', 'bar')``.
-
- .. attribute:: attrs
-
- A dict of HTML attribute strings which should be added to this column.
- Example: ``attrs={"data-foo": "bar"}``.
-
- .. attribute:: truncate
-
- An integer for the maximum length of the string in this column. If the
- data in this column is larger than the supplied number, the data for
- this column will be truncated and an ellipsis will be appended to the
- truncated data.
- Defaults to ``None``.
-
- .. attribute:: link_classes
-
- An iterable of CSS classes which will be added when the column's text
- is displayed as a link.
- Example: ``classes=('link-foo', 'link-bar')``.
- Defaults to ``None``.
- """
- summation_methods = {
- "sum": sum,
- "average": lambda data: sum(data, 0.0) / len(data)
- }
- # Used to retain order when instantiating columns on a table
- creation_counter = 0
-
- transform = None
- name = None
- verbose_name = None
- status_choices = (
- ('enabled', True),
- ('true', True),
- ('up', True),
- ('active', True),
- ('on', True),
- ('none', None),
- ('unknown', None),
- ('', None),
- ('disabled', False),
- ('down', False),
- ('false', False),
- ('inactive', False),
- ('off', False),
- )
-
- def __init__(self, transform, verbose_name=None, sortable=True,
- link=None, allowed_data_types=[], hidden=False, attrs=None,
- status=False, status_choices=None, display_choices=None,
- empty_value=None, filters=None, classes=None, summation=None,
- auto=None, truncate=None, link_classes=None,
- # FIXME: Added for TableStep:
- form_widget=None, form_widget_attributes=None
- ):
-
- self.classes = list(classes or getattr(self, "classes", []))
- super(Column, self).__init__()
- self.attrs.update(attrs or {})
-
- if callable(transform):
- self.transform = transform
- self.name = transform.__name__
- else:
- self.transform = unicode(transform)
- self.name = self.transform
-
- # Empty string is a valid value for verbose_name
- if verbose_name is None:
- verbose_name = self.transform.title()
- else:
- verbose_name = verbose_name
-
- self.auto = auto
- self.sortable = sortable
- self.verbose_name = verbose_name
- self.link = link
- self.allowed_data_types = allowed_data_types
- self.hidden = hidden
- self.status = status
- self.empty_value = empty_value or '-'
- self.filters = filters or []
- self.truncate = truncate
- self.link_classes = link_classes or []
- self.form_widget = form_widget # FIXME: TableStep
- self.form_widget_attributes = form_widget_attributes or {} # TableStep
-
- if status_choices:
- self.status_choices = status_choices
- self.display_choices = display_choices
-
- if summation is not None and summation not in self.summation_methods:
- raise ValueError("Summation method %s must be one of %s."
- % (summation,
- ", ".join(self.summation_methods.keys())))
- self.summation = summation
-
- self.creation_counter = Column.creation_counter
- Column.creation_counter += 1
-
- if self.sortable and not self.auto:
- self.classes.append("sortable")
- if self.hidden:
- self.classes.append("hide")
- if self.link is not None:
- self.classes.append('anchor')
-
- def __unicode__(self):
- return unicode(self.verbose_name)
-
- def __repr__(self):
- return '<%s: %s>' % (self.__class__.__name__, self.name)
-
- def get_raw_data(self, datum):
- """
- Returns the raw data for this column, before any filters or formatting
- are applied to it. This is useful when doing calculations on data in
- the table.
- """
- # Callable transformations
- if callable(self.transform):
- data = self.transform(datum)
- # Basic object lookups
- elif hasattr(datum, self.transform):
- data = getattr(datum, self.transform, None)
- # Dict lookups
- elif isinstance(datum, collections.Iterable) and \
- self.transform in datum:
- data = datum.get(self.transform)
- else:
- if settings.DEBUG:
- msg = _("The attribute %(attr)s doesn't exist on "
- "%(obj)s.") % {'attr': self.transform, 'obj': datum}
- msg = termcolors.colorize(msg, **PALETTE['ERROR'])
- LOG.warning(msg)
- data = None
- return data
-
- def get_data(self, datum):
- """
- Returns the final display data for this column from the given inputs.
-
- The return value will be either the attribute specified for this column
- or the return value of the attr:`~horizon.tables.Column.transform`
- method for this column.
- """
- datum_id = self.table.get_object_id(datum)
-
- if datum_id in self.table._data_cache[self]:
- return self.table._data_cache[self][datum_id]
-
- data = self.get_raw_data(datum)
- display_value = None
-
- if self.display_choices:
- display_value = [display for (value, display) in
- self.display_choices
- if value.lower() == (data or '').lower()]
-
- if display_value:
- data = display_value[0]
- else:
- for filter_func in self.filters:
- data = filter_func(data)
-
- if data and self.truncate:
- data = truncatechars(data, self.truncate)
-
- self.table._data_cache[self][datum_id] = data
-
- return self.table._data_cache[self][datum_id]
-
- def get_link_url(self, datum):
- """ Returns the final value for the column's ``link`` property.
-
- If ``allowed_data_types`` of this column is not empty and the datum
- has an assigned type, check if the datum's type is in the
- ``allowed_data_types`` list. If not, the datum won't be displayed
- as a link.
-
- If ``link`` is a callable, it will be passed the current data object
- and should return a URL. Otherwise ``get_link_url`` will attempt to
- call ``reverse`` on ``link`` with the object's id as a parameter.
- Failing that, it will simply return the value of ``link``.
- """
- if self.allowed_data_types:
- data_type_name = self.table._meta.data_type_name
- data_type = getattr(datum, data_type_name, None)
- if data_type and (data_type not in self.allowed_data_types):
- return None
- obj_id = self.table.get_object_id(datum)
- if callable(self.link):
- return self.link(datum)
- try:
- return urlresolvers.reverse(self.link, args=(obj_id,))
- except urlresolvers.NoReverseMatch:
- return self.link
-
- def get_summation(self):
- """
- Returns the summary value for the data in this column if a
- valid summation method is specified for it. Otherwise returns ``None``.
- """
- if self.summation not in self.summation_methods:
- return None
-
- summation_function = self.summation_methods[self.summation]
- data = [self.get_raw_data(datum) for datum in self.table.data]
- data = filter(lambda datum: datum is not None, data)
-
- if len(data):
- summation = summation_function(data)
- for filter_func in self.filters:
- summation = filter_func(summation)
- return summation
- else:
- return None
-
-
-class Row(html.HTMLElement):
- """ Represents a row in the table.
-
- When iterated, the ``Row`` instance will yield each of its cells.
-
- Rows are capable of AJAX updating, with a little added work:
-
- The ``ajax`` property needs to be set to ``True``, and
- subclasses need to define a ``get_data`` method which returns a data
- object appropriate for consumption by the table (effectively the "get"
- lookup versus the table's "list" lookup).
-
- The automatic update interval is configurable by setting the key
- ``ajax_poll_interval`` in the ``HORIZON_CONFIG`` dictionary.
- Default: ``2500`` (measured in milliseconds).
-
- .. attribute:: table
-
- The table which this row belongs to.
-
- .. attribute:: datum
-
- The data object which this row represents.
-
- .. attribute:: id
-
- A string uniquely representing this row composed of the table name
- and the row data object's identifier.
-
- .. attribute:: cells
-
- The cells belonging to this row stored in a ``SortedDict`` object.
- This attribute is populated during instantiation.
-
- .. attribute:: status
-
- Boolean value representing the status of this row calculated from
- the values of the table's ``status_columns`` if they are set.
-
- .. attribute:: status_class
-
- Returns a css class for the status of the row based on ``status``.
-
- .. attribute:: ajax
-
- Boolean value to determine whether ajax updating for this row is
- enabled.
-
- .. attribute:: ajax_action_name
-
- String that is used for the query parameter key to request AJAX
- updates. Generally you won't need to change this value.
- Default: ``"row_update"``.
- """
- ajax = False
- ajax_action_name = "row_update"
-
- def __init__(self, table, datum=None):
- super(Row, self).__init__()
- self.table = table
- self.datum = datum
- self.selected = False
- if self.datum:
- self.load_cells()
- else:
- self.id = None
- self.cells = []
-
- def load_cells(self, datum=None):
- """
- Load the row's data (either provided at initialization or as an
- argument to this function), initiailize all the cells contained
- by this row, and set the appropriate row properties which require
- the row's data to be determined.
-
- This function is called automatically by
- :meth:`~horizon.tables.Row.__init__` if the ``datum`` argument is
- provided. However, by not providing the data during initialization
- this function allows for the possibility of a two-step loading
- pattern when you need a row instance but don't yet have the data
- available.
- """
- # Compile all the cells on instantiation.
- table = self.table
- if datum:
- self.datum = datum
- else:
- datum = self.datum
- cells = []
- for column in table.columns.values():
- if column.auto == "multi_select":
-
- # FIXME: TableStep code modified
- # multi_select fields in the table must be checked after
- # a server action
- # TODO(remove this ugly code and create proper TableFormWidget)
- multi_select_values = []
- if (getattr(table, 'request', False) and
- getattr(table.request, 'POST', False)):
- multi_select_values = table.request.POST.getlist(
- self.table._meta.multi_select_name)
-
- multi_select_values += getattr(table,
- 'active_multi_select_values',
- [])
-
- if unicode(table.get_object_id(datum)) in multi_select_values:
- multi_select_value = lambda value: True
- else:
- multi_select_value = lambda value: False
- widget = forms.CheckboxInput(check_test=multi_select_value)
-
- # Convert value to string to avoid accidental type conversion
- data = widget.render(self.table._meta.multi_select_name,
- unicode(table.get_object_id(datum)))
- # FIXME: end of added TableStep code
-
- table._data_cache[column][table.get_object_id(datum)] = data
- elif column.auto == "form_widget": # FIXME: Added for TableStep:
- widget = column.form_widget
- widget_name = "%s__%s__%s" % \
- (self.table._meta.multi_select_name,
- column.name,
- unicode(table.get_object_id(datum)))
-
- data = widget.render(widget_name,
- column.get_data(datum),
- column.form_widget_attributes)
- table._data_cache[column][table.get_object_id(datum)] = data
- elif column.auto == "actions":
- data = table.render_row_actions(datum)
- table._data_cache[column][table.get_object_id(datum)] = data
- else:
- data = column.get_data(datum)
- cell = Cell(datum, data, column, self)
- cells.append((column.name or column.auto, cell))
- self.cells = SortedDict(cells)
-
- if self.ajax:
- interval = conf.HORIZON_CONFIG['ajax_poll_interval']
- self.attrs['data-update-interval'] = interval
- self.attrs['data-update-url'] = self.get_ajax_update_url()
- self.classes.append("ajax-update")
-
- # Add the row's status class and id to the attributes to be rendered.
- self.classes.append(self.status_class)
- id_vals = {"table": self.table.name,
- "sep": STRING_SEPARATOR,
- "id": table.get_object_id(datum)}
- self.id = "%(table)s%(sep)srow%(sep)s%(id)s" % id_vals
- self.attrs['id'] = self.id
-
- # Add the row's display name if available
- display_name = table.get_object_display(datum)
- if display_name:
- self.attrs['data-display'] = escape(display_name)
-
- def __repr__(self):
- return '<%s: %s>' % (self.__class__.__name__, self.id)
-
- def __iter__(self):
- return iter(self.cells.values())
-
- @property
- def status(self):
- column_names = self.table._meta.status_columns
- if column_names:
- statuses = dict([(column_name, self.cells[column_name].status) for
- column_name in column_names])
- return self.table.calculate_row_status(statuses)
-
- @property
- def status_class(self):
- column_names = self.table._meta.status_columns
- if column_names:
- return self.table.get_row_status_class(self.status)
- else:
- return ''
-
- def render(self):
- return render_to_string("horizon/common/_data_table_row.html",
- {"row": self})
-
- def get_cells(self):
- """ Returns the bound cells for this row in order. """
- return self.cells.values()
-
- def get_ajax_update_url(self):
- table_url = self.table.get_absolute_url()
- params = urlencode({"table": self.table.name,
- "action": self.ajax_action_name,
- "obj_id": self.table.get_object_id(self.datum)})
- return "%s?%s" % (table_url, params)
-
- def get_data(self, request, obj_id):
- """
- Fetches the updated data for the row based on the object id
- passed in. Must be implemented by a subclass to allow AJAX updating.
- """
- raise NotImplementedError("You must define a get_data method on %s"
- % self.__class__.__name__)
-
-
-class Cell(html.HTMLElement):
- """ Represents a single cell in the table. """
- def __init__(self, datum, data, column, row, attrs=None, classes=None):
- self.classes = classes or getattr(self, "classes", [])
- super(Cell, self).__init__()
- self.attrs.update(attrs or {})
-
- self.datum = datum
- self.data = data
- self.column = column
- self.row = row
-
- def __repr__(self):
- return '<%s: %s, %s>' % (self.__class__.__name__,
- self.column.name,
- self.row.id)
-
- @property
- def value(self):
- """
- Returns a formatted version of the data for final output.
-
- This takes into consideration the
- :attr:`~horizon.tables.Column.link`` and
- :attr:`~horizon.tables.Column.empty_value`
- attributes.
- """
- try:
- data = self.column.get_data(self.datum)
- if data is None:
- if callable(self.column.empty_value):
- data = self.column.empty_value(self.datum)
- else:
- data = self.column.empty_value
- except:
- data = None
- exc_info = sys.exc_info()
- raise template.TemplateSyntaxError, exc_info[1], exc_info[2]
- if self.url:
- link_classes = ' '.join(self.column.link_classes)
- # Escape the data inside while allowing our HTML to render
- data = mark_safe('<a href="%s" class="%s">%s</a>' %
- (self.url, link_classes, escape(data)))
- return data
-
- @property
- def url(self):
- if self.column.link:
- url = self.column.get_link_url(self.datum)
- if url:
- return url
- else:
- return None
-
- @property
- def status(self):
- """ Gets the status for the column based on the cell's data. """
- # Deal with status column mechanics based in this cell's data
- if hasattr(self, '_status'):
- return self._status
-
- if self.column.status or \
- self.column.name in self.column.table._meta.status_columns:
- #returns the first matching status found
- data_value_lower = unicode(self.data).lower()
- for status_name, status_value in self.column.status_choices:
- if unicode(status_name).lower() == data_value_lower:
- self._status = status_value
- return self._status
- self._status = None
- return self._status
-
- def get_status_class(self, status):
- """ Returns a css class name determined by the status value. """
- if status is True:
- return "status_up"
- elif status is False:
- return "status_down"
- else:
- return "status_unknown"
-
- def get_default_classes(self):
- """ Returns a flattened string of the cell's CSS classes. """
- if not self.url:
- self.column.classes = [cls for cls in self.column.classes
- if cls != "anchor"]
- column_class_string = self.column.get_final_attrs().get('class', "")
- classes = set(column_class_string.split(" "))
- if self.column.status:
- classes.add(self.get_status_class(self.status))
- return list(classes)
-
-
-class DataTableOptions(object):
- """ Contains options for :class:`.DataTable` objects.
-
- .. attribute:: name
-
- A short name or slug for the table.
-
- .. attribute:: verbose_name
-
- A more verbose name for the table meant for display purposes.
-
- .. attribute:: columns
-
- A list of column objects or column names. Controls ordering/display
- of the columns in the table.
-
- .. attribute:: table_actions
-
- A list of action classes derived from the
- :class:`~horizon.tables.Action` class. These actions will handle tasks
- such as bulk deletion, etc. for multiple objects at once.
-
- .. attribute:: row_actions
-
- A list similar to ``table_actions`` except tailored to appear for
- each row. These actions act on a single object at a time.
-
- .. attribute:: actions_column
-
- Boolean value to control rendering of an additional column containing
- the various actions for each row. Defaults to ``True`` if any actions
- are specified in the ``row_actions`` option.
-
- .. attribute:: multi_select
-
- Boolean value to control rendering of an extra column with checkboxes
- for selecting multiple objects in the table. Defaults to ``True`` if
- any actions are specified in the ``table_actions`` option.
-
- .. attribute:: filter
-
- Boolean value to control the display of the "filter" search box
- in the table actions. By default it checks whether or not an instance
- of :class:`.FilterAction` is in :attr:`.table_actions`.
-
- .. attribute:: template
-
- String containing the template which should be used to render the
- table. Defaults to ``"horizon/common/_data_table.html"``.
-
- .. attribute:: context_var_name
-
- The name of the context variable which will contain the table when
- it is rendered. Defaults to ``"table"``.
-
- .. attribute:: pagination_param
-
- The name of the query string parameter which will be used when
- paginating this table. When using multiple tables in a single
- view this will need to be changed to differentiate between the
- tables. Default: ``"marker"``.
-
- .. attribute:: status_columns
-
- A list or tuple of column names which represents the "state"
- of the data object being represented.
-
- If ``status_columns`` is set, when the rows are rendered the value
- of this column will be used to add an extra class to the row in
- the form of ``"status_up"`` or ``"status_down"`` for that row's
- data.
-
- The row status is used by other Horizon components to trigger tasks
- such as dynamic AJAX updating.
-
- .. attribute:: row_class
-
- The class which should be used for rendering the rows of this table.
- Optional. Default: :class:`~horizon.tables.Row`.
-
- .. attribute:: column_class
-
- The class which should be used for handling the columns of this table.
- Optional. Default: :class:`~horizon.tables.Column`.
-
- .. attribute:: mixed_data_type
-
- A toggle to indicate if the table accepts two or more types of data.
- Optional. Default: :``False``
-
- .. attribute:: data_types
-
- A list of data types that this table would accept. Default to be an
- empty list, but if the attibute ``mixed_data_type`` is set to ``True``,
- then this list must have at least one element.
-
- .. attribute:: data_type_name
-
- The name of an attribute to assign to data passed to the table when it
- accepts mix data. Default: ``"_table_data_type"``
-
- .. attribute:: footer
-
- Boolean to control whether or not to show the table's footer.
- Default: ``True``.
-
- .. attribute:: permissions
-
- A list of permission names which this table requires in order to be
- displayed. Defaults to an empty list (``[]``).
- """
- def __init__(self, options):
- self.name = getattr(options, 'name', self.__class__.__name__)
- verbose_name = getattr(options, 'verbose_name', None) \
- or self.name.title()
- self.verbose_name = verbose_name
- self.columns = getattr(options, 'columns', None)
- self.status_columns = getattr(options, 'status_columns', [])
- self.table_actions = getattr(options, 'table_actions', [])
- self.row_actions = getattr(options, 'row_actions', [])
- self.row_class = getattr(options, 'row_class', Row)
- self.column_class = getattr(options, 'column_class', Column)
- self.pagination_param = getattr(options, 'pagination_param', 'marker')
- self.browser_table = getattr(options, 'browser_table', None)
- self.footer = getattr(options, 'footer', True)
- self.no_data_message = getattr(options,
- "no_data_message",
- _("No items to display."))
- self.permissions = getattr(options, 'permissions', [])
-
- # Set self.filter if we have any FilterActions
- filter_actions = [action for action in self.table_actions if
- issubclass(action, FilterAction)]
- if len(filter_actions) > 1:
- raise NotImplementedError("Multiple filter actions is not "
- "currently supported.")
- self.filter = getattr(options, 'filter', len(filter_actions) > 0)
- if len(filter_actions) == 1:
- self._filter_action = filter_actions.pop()
- else:
- self._filter_action = None
-
- self.template = 'horizon/common/_data_table.html'
- self.row_actions_template = \
- 'horizon/common/_data_table_row_actions.html'
- self.table_actions_template = \
- 'horizon/common/_data_table_table_actions.html'
- self.context_var_name = unicode(getattr(options,
- 'context_var_name',
- 'table'))
- self.actions_column = getattr(options,
- 'actions_column',
- len(self.row_actions) > 0)
- # FIXME: TableStep
- self.multi_select_name = getattr(options,
- 'multi_select_name',
- 'object_ids')
- self.multi_select = getattr(options,
- 'multi_select',
- len(self.table_actions) > 0)
-
- # Set runtime table defaults; not configurable.
- self.has_more_data = False
-
- # Set mixed data type table attr
- self.mixed_data_type = getattr(options, 'mixed_data_type', False)
- self.data_types = getattr(options, 'data_types', [])
-
- # If the data_types has more than 2 elements, set mixed_data_type
- # to True automatically.
- if len(self.data_types) > 1:
- self.mixed_data_type = True
-
- # However, if the mixed_data_type is set to True manually and the
- # the data_types is empty, raise an errror.
- if self.mixed_data_type and len(self.data_types) <= 1:
- raise ValueError("If mixed_data_type is set to True in class %s, "
- "data_types should has more than one types" %
- self.name)
-
- self.data_type_name = getattr(options,
- 'data_type_name',
- "_table_data_type")
-
-
-class DataTableMetaclass(type):
- """ Metaclass to add options to DataTable class and collect columns. """
- def __new__(mcs, name, bases, attrs):
- # Process options from Meta
- class_name = name
- attrs["_meta"] = opts = DataTableOptions(attrs.get("Meta", None))
-
- # Gather columns; this prevents the column from being an attribute
- # on the DataTable class and avoids naming conflicts.
- columns = []
- for attr_name, obj in attrs.items():
- if issubclass(type(obj), (opts.column_class, Column)):
- column_instance = attrs.pop(attr_name)
- column_instance.name = attr_name
- column_instance.classes.append('normal_column')
- columns.append((attr_name, column_instance))
- columns.sort(key=lambda x: x[1].creation_counter)
-
- # Iterate in reverse to preserve final order
- for base in bases[::-1]:
- if hasattr(base, 'base_columns'):
- columns = base.base_columns.items() + columns
- attrs['base_columns'] = SortedDict(columns)
-
- # If the table is in a ResourceBrowser, the column number must meet
- # these limits because of the width of the browser.
- if opts.browser_table == "navigation" and len(columns) > 1:
- raise ValueError("You can only assign one column to %s."
- % class_name)
- if opts.browser_table == "content" and len(columns) > 2:
- raise ValueError("You can only assign two columns to %s."
- % class_name)
-
- if opts.columns:
- # Remove any columns that weren't declared if we're being explicit
- # NOTE: we're iterating a COPY of the list here!
- for column_data in columns[:]:
- if column_data[0] not in opts.columns:
- columns.pop(columns.index(column_data))
- # Re-order based on declared columns
- columns.sort(key=lambda x: attrs['_meta'].columns.index(x[0]))
- # Add in our auto-generated columns
- if opts.multi_select and opts.browser_table != "navigation":
- multi_select = opts.column_class("multi_select",
- verbose_name="",
- auto="multi_select")
- multi_select.classes.append('multi_select_column')
- columns.insert(0, ("multi_select", multi_select))
- if opts.actions_column:
- actions_column = opts.column_class("actions",
- verbose_name=_("Actions"),
- auto="actions")
- actions_column.classes.append('actions_column')
- columns.append(("actions", actions_column))
- # Store this set of columns internally so we can copy them per-instance
- attrs['_columns'] = SortedDict(columns)
-
- # Gather and register actions for later access since we only want
- # to instantiate them once.
- # (list() call gives deterministic sort order, which sets don't have.)
- actions = list(set(opts.row_actions) | set(opts.table_actions))
- actions.sort(key=attrgetter('name'))
- actions_dict = SortedDict([(action.name, action())
- for action in actions])
- attrs['base_actions'] = actions_dict
- if opts._filter_action:
- # Replace our filter action with the instantiated version
- opts._filter_action = actions_dict[opts._filter_action.name]
-
- # Create our new class!
- return type.__new__(mcs, name, bases, attrs)
-
-
-class DataTable(object):
- """ A class which defines a table with all data and associated actions.
-
- .. attribute:: name
-
- String. Read-only access to the name specified in the
- table's Meta options.
-
- .. attribute:: multi_select
-
- Boolean. Read-only access to whether or not this table
- should display a column for multi-select checkboxes.
-
- .. attribute:: data
-
- Read-only access to the data this table represents.
-
- .. attribute:: filtered_data
-
- Read-only access to the data this table represents, filtered by
- the :meth:`~horizon.tables.FilterAction.filter` method of the table's
- :class:`~horizon.tables.FilterAction` class (if one is provided)
- using the current request's query parameters.
- """
- __metaclass__ = DataTableMetaclass
-
- def __init__(self, request, data=None, needs_form_wrapper=None, **kwargs):
- self.request = request
- self.data = data
- self.kwargs = kwargs
- self._needs_form_wrapper = needs_form_wrapper
- self._no_data_message = self._meta.no_data_message
- self.breadcrumb = None
- self.current_item_id = None
- self.permissions = self._meta.permissions
-
- # Create a new set
- columns = []
- for key, _column in self._columns.items():
- column = copy.copy(_column)
- column.table = self
- columns.append((key, column))
- self.columns = SortedDict(columns)
- self._populate_data_cache()
-
- # Associate these actions with this table
- for action in self.base_actions.values():
- action.table = self
-
- self.needs_summary_row = any([col.summation
- for col in self.columns.values()])
-
- def __unicode__(self):
- return unicode(self._meta.verbose_name)
-
- def __repr__(self):
- return '<%s: %s>' % (self.__class__.__name__, self._meta.name)
-
- @property
- def name(self):
- return self._meta.name
-
- @property
- def footer(self):
- return self._meta.footer
-
- @property
- def multi_select(self):
- return self._meta.multi_select
-
- @property
- def filtered_data(self):
- if not hasattr(self, '_filtered_data'):
- self._filtered_data = self.data
- if self._meta.filter and self._meta._filter_action:
- action = self._meta._filter_action
- filter_string = self.get_filter_string()
- request_method = self.request.method
- needs_preloading = (not filter_string
- and request_method == 'GET'
- and action.needs_preloading)
- valid_method = (request_method == action.method)
- if (filter_string and valid_method) or needs_preloading:
- if self._meta.mixed_data_type:
- self._filtered_data = action.data_type_filter(self,
- self.data,
- filter_string)
- else:
- self._filtered_data = action.filter(self,
- self.data,
- filter_string)
- return self._filtered_data
-
- def get_filter_string(self):
- filter_action = self._meta._filter_action
- param_name = filter_action.get_param_name()
- filter_string = self.request.POST.get(param_name, '')
- return filter_string
-
- def _populate_data_cache(self):
- self._data_cache = {}
- # Set up hash tables to store data points for each column
- for column in self.get_columns():
- self._data_cache[column] = {}
-
- def _filter_action(self, action, request, datum=None):
- try:
- # Catch user errors in permission functions here
- row_matched = True
- if self._meta.mixed_data_type:
- row_matched = action.data_type_matched(datum)
- return action._allowed(request, datum) and row_matched
- except Exception:
- LOG.exception("Error while checking action permissions.")
- return None
-
- def is_browser_table(self):
- if self._meta.browser_table:
- return True
- return False
-
- def render(self):
- """ Renders the table using the template from the table options. """
- table_template = template.loader.get_template(self._meta.template)
- extra_context = {self._meta.context_var_name: self}
- context = template.RequestContext(self.request, extra_context)
- return table_template.render(context)
-
- def get_absolute_url(self):
- """ Returns the canonical URL for this table.
-
- This is used for the POST action attribute on the form element
- wrapping the table. In many cases it is also useful for redirecting
- after a successful action on the table.
-
- For convenience it defaults to the value of
- ``request.get_full_path()`` with any query string stripped off,
- e.g. the path at which the table was requested.
- """
- return self.request.get_full_path().partition('?')[0]
-
- def get_empty_message(self):
- """ Returns the message to be displayed when there is no data. """
- return self._no_data_message
-
- def get_object_by_id(self, lookup):
- """
- Returns the data object from the table's dataset which matches
- the ``lookup`` parameter specified. An error will be raised if
- the match is not a single data object.
-
- We will convert the object id and ``lookup`` to unicode before
- comparison.
-
- Uses :meth:`~horizon.tables.DataTable.get_object_id` internally.
- """
- if not isinstance(lookup, unicode):
- lookup = unicode(str(lookup), 'utf-8')
- matches = []
- for datum in self.data:
- obj_id = self.get_object_id(datum)
- if not isinstance(obj_id, unicode):
- obj_id = unicode(str(obj_id), 'utf-8')
- if obj_id == lookup:
- matches.append(datum)
- if len(matches) > 1:
- raise ValueError("Multiple matches were returned for that id: %s."
- % matches)
- if not matches:
- raise exceptions.Http302(self.get_absolute_url(),
- _('No match returned for the id "%s".')
- % lookup)
- return matches[0]
-
- @property
- def has_actions(self):
- """
- Boolean. Indicates whether there are any available actions on this
- table.
- """
- if not self.base_actions:
- return False
- return any(self.get_table_actions()) or any(self._meta.row_actions)
-
- @property
- def needs_form_wrapper(self):
- """
- Boolean. Indicates whather this table should be rendered wrapped in
- a ``<form>`` tag or not.
- """
- # If needs_form_wrapper is explicitly set, defer to that.
- if self._needs_form_wrapper is not None:
- return self._needs_form_wrapper
- # Otherwise calculate whether or not we need a form element.
- return self.has_actions
-
- def get_table_actions(self):
- """ Returns a list of the action instances for this table. """
- bound_actions = [self.base_actions[action.name] for
- action in self._meta.table_actions]
- return [action for action in bound_actions if
- self._filter_action(action, self.request)]
-
- def get_row_actions(self, datum):
- """ Returns a list of the action instances for a specific row. """
- bound_actions = []
- for action in self._meta.row_actions:
- # Copy to allow modifying properties per row
- bound_action = copy.copy(self.base_actions[action.name])
- bound_action.attrs = copy.copy(bound_action.attrs)
- bound_action.datum = datum
- # Remove disallowed actions.
- if not self._filter_action(bound_action,
- self.request,
- datum):
- continue
- # Hook for modifying actions based on data. No-op by default.
- bound_action.update(self.request, datum)
- # Pre-create the URL for this link with appropriate parameters
- if issubclass(bound_action.__class__, LinkAction):
- bound_action.bound_url = bound_action.get_link_url(datum)
- bound_actions.append(bound_action)
- return bound_actions
-
- def render_table_actions(self):
- """ Renders the actions specified in ``Meta.table_actions``. """
- template_path = self._meta.table_actions_template
- table_actions_template = template.loader.get_template(template_path)
- bound_actions = self.get_table_actions()
- extra_context = {"table_actions": bound_actions}
- if self._meta.filter and \
- self._filter_action(self._meta._filter_action, self.request):
- extra_context["filter"] = self._meta._filter_action
- context = template.RequestContext(self.request, extra_context)
- return table_actions_template.render(context)
-
- def render_row_actions(self, datum):
- """
- Renders the actions specified in ``Meta.row_actions`` using the
- current row data. """
- template_path = self._meta.row_actions_template
- row_actions_template = template.loader.get_template(template_path)
- bound_actions = self.get_row_actions(datum)
- extra_context = {"row_actions": bound_actions,
- "row_id": self.get_object_id(datum)}
- context = template.RequestContext(self.request, extra_context)
- return row_actions_template.render(context)
-
- @staticmethod
- def parse_action(action_string):
- """
- Parses the ``action`` parameter (a string) sent back with the
- POST data. By default this parses a string formatted as
- ``{{ table_name }}__{{ action_name }}__{{ row_id }}`` and returns
- each of the pieces. The ``row_id`` is optional.
- """
- if action_string:
- bits = action_string.split(STRING_SEPARATOR)
- bits.reverse()
- table = bits.pop()
- action = bits.pop()
- try:
- object_id = bits.pop()
- except IndexError:
- object_id = None
- return table, action, object_id
-
- def take_action(self, action_name, obj_id=None, obj_ids=None):
- """
- Locates the appropriate action and routes the object
- data to it. The action should return an HTTP redirect
- if successful, or a value which evaluates to ``False``
- if unsuccessful.
- """
- # See if we have a list of ids
- obj_ids = obj_ids or self.request.POST.getlist('object_ids')
- action = self.base_actions.get(action_name, None)
- if not action or action.method != self.request.method:
- # We either didn't get an action or we're being hacked. Goodbye.
- return None
-
- # Meanhile, back in Gotham...
- if not action.requires_input or obj_id or obj_ids:
- if obj_id:
- obj_id = self.sanitize_id(obj_id)
- if obj_ids:
- obj_ids = [self.sanitize_id(i) for i in obj_ids]
- # Single handling is easy
- if not action.handles_multiple:
- response = action.single(self, self.request, obj_id)
- # Otherwise figure out what to pass along
- else:
- # Preference given to a specific id, since that implies
- # the user selected an action for just one row.
- if obj_id:
- obj_ids = [obj_id]
- response = action.multiple(self, self.request, obj_ids)
- return response
- elif action and action.requires_input and not (obj_id or obj_ids):
- messages.info(self.request,
- _("Please select a row before taking that action."))
- return None
-
- @classmethod
- def check_handler(cls, request):
- """ Determine whether the request should be handled by this table. """
- if request.method == "POST" and "action" in request.POST:
- table, action, obj_id = cls.parse_action(request.POST["action"])
- elif "table" in request.GET and "action" in request.GET:
- table = request.GET["table"]
- action = request.GET["action"]
- obj_id = request.GET.get("obj_id", None)
- else:
- table = action = obj_id = None
- return table, action, obj_id
-
- def maybe_preempt(self):
- """
- Determine whether the request should be handled by a preemptive action
- on this table or by an AJAX row update before loading any data.
- """
- request = self.request
- table_name, action_name, obj_id = self.check_handler(request)
-
- if table_name == self.name:
- # Handle AJAX row updating.
- new_row = self._meta.row_class(self)
- if new_row.ajax and new_row.ajax_action_name == action_name:
- try:
- datum = new_row.get_data(request, obj_id)
- new_row.load_cells(datum)
- error = False
- except:
- datum = None
- error = exceptions.handle(request, ignore=True)
- if request.is_ajax():
- if not error:
- return HttpResponse(new_row.render())
- else:
- return HttpResponse(status=error.status_code)
-
- preemptive_actions = [action for action in
- self.base_actions.values() if action.preempt]
- if action_name:
- for action in preemptive_actions:
- if action.name == action_name:
- handled = self.take_action(action_name, obj_id)
- if handled:
- return handled
- return None
-
- def maybe_handle(self):
- """
- Determine whether the request should be handled by any action on this
- table after data has been loaded.
- """
- request = self.request
- table_name, action_name, obj_id = self.check_handler(request)
- if table_name == self.name and action_name:
- return self.take_action(action_name, obj_id)
- return None
-
- def sanitize_id(self, obj_id):
- """ Override to modify an incoming obj_id to match existing
- API data types or modify the format.
- """
- return obj_id
-
- def get_object_id(self, datum):
- """ Returns the identifier for the object this row will represent.
-
- By default this returns an ``id`` attribute on the given object,
- but this can be overridden to return other values.
-
- .. warning::
-
- Make sure that the value returned is a unique value for the id
- otherwise rendering issues can occur.
- """
- return datum.id
-
- def get_object_display(self, datum):
- """ Returns a display name that identifies this object.
-
- By default, this returns a ``name`` attribute from the given object,
- but this can be overriden to return other values.
- """
- if hasattr(datum, 'name'):
- return datum.name
- return None
-
- def has_more_data(self):
- """
- Returns a boolean value indicating whether there is more data
- available to this table from the source (generally an API).
-
- The method is largely meant for internal use, but if you want to
- override it to provide custom behavior you can do so at your own risk.
- """
- return self._meta.has_more_data
-
- def get_marker(self):
- """
- Returns the identifier for the last object in the current data set
- for APIs that use marker/limit-based paging.
- """
- return http.urlquote_plus(self.get_object_id(self.data[-1]))
-
- def get_pagination_string(self):
- """ Returns the query parameter string to paginate this table. """
- return "=".join([self._meta.pagination_param, self.get_marker()])
-
- def calculate_row_status(self, statuses):
- """
- Returns a boolean value determining the overall row status
- based on the dictionary of column name to status mappings passed in.
-
- By default, it uses the following logic:
-
- #. If any statuses are ``False``, return ``False``.
- #. If no statuses are ``False`` but any or ``None``, return ``None``.
- #. If all statuses are ``True``, return ``True``.
-
- This provides the greatest protection against false positives without
- weighting any particular columns.
-
- The ``statuses`` parameter is passed in as a dictionary mapping
- column names to their statuses in order to allow this function to
- be overridden in such a way as to weight one column's status over
- another should that behavior be desired.
- """
- values = statuses.values()
- if any([status is False for status in values]):
- return False
- elif any([status is None for status in values]):
- return None
- else:
- return True
-
- def get_row_status_class(self, status):
- """
- Returns a css class name determined by the status value. This class
- name is used to indicate the status of the rows in the table if
- any ``status_columns`` have been specified.
- """
- if status is True:
- return "status_up"
- elif status is False:
- return "status_down"
- else:
- return "status_unknown"
-
- def get_columns(self):
- """ Returns this table's columns including auto-generated ones."""
- return self.columns.values()
-
- def get_rows(self):
- """ Return the row data for this table broken out by columns. """
- rows = []
- try:
- for datum in self.filtered_data:
- row = self._meta.row_class(self, datum)
- if self.get_object_id(datum) == self.current_item_id:
- self.selected = True
- row.classes.append('current_selected')
- rows.append(row)
- except:
- # Exceptions can be swallowed at the template level here,
- # re-raising as a TemplateSyntaxError makes them visible.
- LOG.exception("Error while rendering table rows.")
- exc_info = sys.exc_info()
- raise template.TemplateSyntaxError, exc_info[1], exc_info[2]
- return rows
diff --git a/horizon/tables/views.py b/horizon/tables/views.py
deleted file mode 100644
index ad7dc433..00000000
--- a/horizon/tables/views.py
+++ /dev/null
@@ -1,261 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from collections import defaultdict
-
-from django.views import generic
-
-from horizon.templatetags.horizon import has_permissions
-
-
-class MultiTableMixin(object):
- """ A generic mixin which provides methods for handling DataTables. """
- data_method_pattern = "get_%s_data"
-
- def __init__(self, *args, **kwargs):
- super(MultiTableMixin, self).__init__(*args, **kwargs)
- self.table_classes = getattr(self, "table_classes", [])
- self._data = {}
- self._tables = {}
-
- self._data_methods = defaultdict(list)
- self.get_data_methods(self.table_classes, self._data_methods)
-
- def _get_data_dict(self):
- if not self._data:
- for table in self.table_classes:
- data = []
- name = table._meta.name
- func_list = self._data_methods.get(name, [])
- for func in func_list:
- data.extend(func())
- self._data[name] = data
- return self._data
-
- def get_data_methods(self, table_classes, methods):
- for table in table_classes:
- name = table._meta.name
- if table._meta.mixed_data_type:
- for data_type in table._meta.data_types:
- func = self.check_method_exist(self.data_method_pattern,
- data_type)
- if func:
- type_name = table._meta.data_type_name
- methods[name].append(self.wrap_func(func,
- type_name,
- data_type))
- else:
- func = self.check_method_exist(self.data_method_pattern,
- name)
- if func:
- methods[name].append(func)
-
- def wrap_func(self, data_func, type_name, data_type):
- def final_data():
- data = data_func()
- self.assign_type_string(data, type_name, data_type)
- return data
- return final_data
-
- def check_method_exist(self, func_pattern="%s", *names):
- func_name = func_pattern % names
- func = getattr(self, func_name, None)
- if not func or not callable(func):
- cls_name = self.__class__.__name__
- raise NotImplementedError("You must define a %s method "
- "in %s." % (func_name, cls_name))
- else:
- return func
-
- def assign_type_string(self, data, type_name, data_type):
- for datum in data:
- setattr(datum, type_name, data_type)
-
- def get_tables(self):
- if not self.table_classes:
- raise AttributeError('You must specify one or more DataTable '
- 'classes for the "table_classes" attribute '
- 'on %s.' % self.__class__.__name__)
- if not self._tables:
- for table in self.table_classes:
- if not has_permissions(self.request.user,
- table._meta):
- continue
- func_name = "get_%s_table" % table._meta.name
- table_func = getattr(self, func_name, None)
- if table_func is None:
- tbl = table(self.request, **self.kwargs)
- else:
- tbl = table_func(self, self.request, **self.kwargs)
- self._tables[table._meta.name] = tbl
- return self._tables
-
- def get_context_data(self, **kwargs):
- context = super(MultiTableMixin, self).get_context_data(**kwargs)
- tables = self.get_tables()
- for name, table in tables.items():
- context["%s_table" % name] = table
- return context
-
- def has_more_data(self, table):
- return False
-
- def handle_table(self, table):
- name = table.name
- data = self._get_data_dict()
- self._tables[name].data = data[table._meta.name]
- self._tables[name]._meta.has_more_data = self.has_more_data(table)
- handled = self._tables[name].maybe_handle()
- return handled
-
-
-class MultiTableView(MultiTableMixin, generic.TemplateView):
- """
- A class-based generic view to handle the display and processing of
- multiple :class:`~horizon.tables.DataTable` classes in a single view.
-
- Three steps are required to use this view: set the ``table_classes``
- attribute with a tuple of the desired
- :class:`~horizon.tables.DataTable` classes;
- define a ``get_{{ table_name }}_data`` method for each table class
- which returns a set of data for that table; and specify a template for
- the ``template_name`` attribute.
- """
- def construct_tables(self):
- tables = self.get_tables().values()
- # Early out before data is loaded
- for table in tables:
- preempted = table.maybe_preempt()
- if preempted:
- return preempted
- # Load data into each table and check for action handlers
- for table in tables:
- handled = self.handle_table(table)
- if handled:
- return handled
-
- # If we didn't already return a response, returning None continues
- # with the view as normal.
- return None
-
- def get(self, request, *args, **kwargs):
- handled = self.construct_tables()
- if handled:
- return handled
- context = self.get_context_data(**kwargs)
- return self.render_to_response(context)
-
- def post(self, request, *args, **kwargs):
- # GET and POST handling are the same
- return self.get(request, *args, **kwargs)
-
-
-class DataTableView(MultiTableView):
- """ A class-based generic view to handle basic DataTable processing.
-
- Three steps are required to use this view: set the ``table_class``
- attribute with the desired :class:`~horizon.tables.DataTable` class;
- define a ``get_data`` method which returns a set of data for the
- table; and specify a template for the ``template_name`` attribute.
-
- Optionally, you can override the ``has_more_data`` method to trigger
- pagination handling for APIs that support it.
- """
- table_class = None
- context_object_name = 'table'
-
- def _get_data_dict(self):
- if not self._data:
- self._data = {self.table_class._meta.name: self.get_data()}
- return self._data
-
- def get_data(self):
- raise NotImplementedError('You must define a "get_data" method on %s.'
- % self.__class__.__name__)
-
- def get_tables(self):
- if not self._tables:
- self._tables = {}
- if has_permissions(self.request.user,
- self.table_class._meta):
- self._tables[self.table_class._meta.name] = self.get_table()
- return self._tables
-
- def get_table(self):
- if not self.table_class:
- raise AttributeError('You must specify a DataTable class for the '
- '"table_class" attribute on %s.'
- % self.__class__.__name__)
- if not hasattr(self, "table"):
- self.table = self.table_class(self.request, **self.kwargs)
- return self.table
-
- def get_context_data(self, **kwargs):
- context = super(DataTableView, self).get_context_data(**kwargs)
- if hasattr(self, "table"):
- context[self.context_object_name] = self.table
- return context
-
-
-class MixedDataTableView(DataTableView):
- """ A class-based generic view to handle DataTable with mixed data
- types.
-
- Basic usage is the same as DataTableView.
-
- Three steps are required to use this view:
- #. Set the ``table_class`` attribute with desired
- :class:`~horizon.tables.DataTable` class. In the class the
- ``data_types`` list should have at least two elements.
-
- #. Define a ``get_{{ data_type }}_data`` method for each data type
- which returns a set of data for the table.
-
- #. Specify a template for the ``template_name`` attribute.
- """
- table_class = None
- context_object_name = 'table'
-
- def _get_data_dict(self):
- if not self._data:
- table = self.table_class
- self._data = {table._meta.name: []}
- for data_type in table.data_types:
- func_name = "get_%s_data" % data_type
- data_func = getattr(self, func_name, None)
- if data_func is None:
- cls_name = self.__class__.__name__
- raise NotImplementedError("You must define a %s method "
- "for %s data type in %s." %
- (func_name, data_type, cls_name))
- data = data_func()
- self.assign_type_string(data, data_type)
- self._data[table._meta.name].extend(data)
- return self._data
-
- def assign_type_string(self, data, type_string):
- for datum in data:
- setattr(datum, self.table_class.data_type_name,
- type_string)
-
- def get_table(self):
- self.table = super(MixedDataTableView, self).get_table()
- if not self.table._meta.mixed_data_type:
- raise AttributeError('You must have at least two elements in '
- 'the data_types attibute '
- 'in table %s to use MixedDataTableView.'
- % self.table._meta.name)
- return self.table
diff --git a/horizon/tabs/__init__.py b/horizon/tabs/__init__.py
deleted file mode 100644
index 75a7ddde..00000000
--- a/horizon/tabs/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from horizon.tabs.base import Tab
-from horizon.tabs.base import TabGroup
-from horizon.tabs.base import TableTab
-from horizon.tabs.views import TabbedTableView
-from horizon.tabs.views import TabView
-
-assert TabGroup
-assert Tab
-assert TableTab
-assert TabView
-assert TabbedTableView
diff --git a/horizon/tabs/base.py b/horizon/tabs/base.py
deleted file mode 100644
index 68da6709..00000000
--- a/horizon/tabs/base.py
+++ /dev/null
@@ -1,459 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import sys
-
-from django.template.loader import render_to_string
-from django.template import TemplateSyntaxError
-from django.utils.datastructures import SortedDict
-
-from horizon import exceptions
-from horizon.utils import html
-
-SEPARATOR = "__"
-CSS_TAB_GROUP_CLASSES = ["nav", "nav-tabs", "ajax-tabs"]
-CSS_ACTIVE_TAB_CLASSES = ["active"]
-CSS_DISABLED_TAB_CLASSES = ["disabled"]
-
-
-class TabGroup(html.HTMLElement):
- """
- A container class which knows how to manage and render
- :class:`~horizon.tabs.Tab` objects.
-
- .. attribute:: slug
-
- The URL slug and pseudo-unique identifier for this tab group.
-
- .. attribute:: template_name
-
- The name of the template which will be used to render this tab group.
- Default: ``"horizon/common/_tab_group.html"``
-
- .. attribute:: sticky
-
- Boolean to control whether the active tab state should be stored
- across requests for a given user. (State storage is all done
- client-side.)
-
- .. attribute:: param_name
-
- The name of the GET request parameter which will be used when
- requesting specific tab data. Default: ``tab``.
-
- .. attribute:: classes
-
- A list of CSS classes which should be displayed on this tab group.
-
- .. attribute:: attrs
-
- A dictionary of HTML attributes which should be rendered into the
- markup for this tab group.
-
- .. attribute:: selected
-
- Read-only property which is set to the instance of the
- currently-selected tab if there is one, otherwise ``None``.
-
- .. attribute:: active
-
- Read-only property which is set to the value of the current active tab.
- This may not be the same as the value of ``selected`` if no
- specific tab was requested via the ``GET`` parameter.
- """
- slug = None
- template_name = "horizon/common/_tab_group.html"
- param_name = 'tab'
- sticky = False
- _selected = None
- _active = None
-
- @property
- def selected(self):
- return self._selected
-
- @property
- def active(self):
- return self._active
-
- def __init__(self, request, **kwargs):
- super(TabGroup, self).__init__()
- if not hasattr(self, "tabs"):
- raise NotImplementedError('%s must declare a "tabs" attribute.'
- % self.__class__)
- self.request = request
- self.kwargs = kwargs
- self._data = None
- tab_instances = []
- for tab in self.tabs:
- tab_instances.append((tab.slug, tab(self, request)))
- self._tabs = SortedDict(tab_instances)
- if self.sticky:
- self.attrs['data-sticky-tabs'] = 'sticky'
- if not self._set_active_tab():
- self.tabs_not_available()
-
- def __repr__(self):
- return "<%s: %s>" % (self.__class__.__name__, self.slug)
-
- def load_tab_data(self):
- """
- Preload all data that for the tabs that will be displayed.
- """
- for tab in self._tabs.values():
- if tab.load and not tab.data_loaded:
- try:
- tab._data = tab.get_context_data(self.request)
- except:
- tab._data = False
- exceptions.handle(self.request)
-
- def get_id(self):
- """
- Returns the id for this tab group. Defaults to the value of the tab
- group's :attr:`horizon.tabs.Tab.slug`.
- """
- return self.slug
-
- def get_default_classes(self):
- """
- Returns a list of the default classes for the tab group. Defaults to
- ``["nav", "nav-tabs", "ajax-tabs"]``.
- """
- default_classes = super(TabGroup, self).get_default_classes()
- default_classes.extend(CSS_TAB_GROUP_CLASSES)
- return default_classes
-
- def tabs_not_available(self):
- """
- In the event that no tabs are either allowed or enabled, this method
- is the fallback handler. By default it's a no-op, but it exists
- to make redirecting or raising exceptions possible for subclasses.
- """
- pass
-
- def _set_active_tab(self):
- marked_active = None
-
- # See if we have a selected tab via the GET parameter.
- tab = self.get_selected_tab()
- if tab:
- tab._active = True
- self._active = tab
- marked_active = tab
-
- # Iterate through to mark them all accordingly.
- for tab in self._tabs.values():
- if tab._allowed and tab._enabled and not marked_active:
- tab._active = True
- self._active = tab
- marked_active = True
- elif tab == marked_active:
- continue
- else:
- tab._active = False
-
- return marked_active
-
- def render(self):
- """ Renders the HTML output for this tab group. """
- return render_to_string(self.template_name, {"tab_group": self})
-
- def get_tabs(self):
- """ Returns a list of the allowed tabs for this tab group. """
- return filter(lambda tab: tab._allowed, self._tabs.values())
-
- def get_tab(self, tab_name, allow_disabled=False):
- """ Returns a specific tab from this tab group.
-
- If the tab is not allowed or not enabled this method returns ``None``.
-
- If the tab is disabled but you wish to return it anyway, you can pass
- ``True`` to the allow_disabled argument.
- """
- tab = self._tabs.get(tab_name, None)
- if tab and tab._allowed and (tab._enabled or allow_disabled):
- return tab
- return None
-
- def get_loaded_tabs(self):
- return filter(lambda t: self.get_tab(t.slug), self._tabs.values())
-
- def get_selected_tab(self):
- """ Returns the tab specific by the GET request parameter.
-
- In the event that there is no GET request parameter, the value
- of the query parameter is invalid, or the tab is not allowed/enabled,
- the return value of this function is None.
- """
- selected = self.request.GET.get(self.param_name, None)
- if selected:
- tab_group, tab_name = selected.split(SEPARATOR)
- if tab_group == self.get_id():
- self._selected = self.get_tab(tab_name)
- return self._selected
-
-
-class Tab(html.HTMLElement):
- """
- A reusable interface for constructing a tab within a
- :class:`~horizon.tabs.TabGroup`.
-
- .. attribute:: name
-
- The display name for the tab which will be rendered as the text for
- the tab element in the HTML. Required.
-
- .. attribute:: slug
-
- The URL slug and id attribute for the tab. This should be unique for
- a given tab group. Required.
-
- .. attribute:: preload
-
- Determines whether the contents of the tab should be rendered into
- the page's HTML when the tab group is rendered, or whether it should
- be loaded dynamically when the tab is selected. Default: ``True``.
-
- .. attribute:: classes
-
- A list of CSS classes which should be displayed on this tab.
-
- .. attribute:: attrs
-
- A dictionary of HTML attributes which should be rendered into the
- markup for this tab.
-
- .. attribute:: load
-
- Read-only access to determine whether or not this tab's data should
- be loaded immediately.
- """
- name = None
- slug = None
- preload = True
- _active = None
-
- def __init__(self, tab_group, request=None):
- super(Tab, self).__init__()
- # Priority: constructor, class-defined, fallback
- if not self.name:
- raise ValueError("%s must have a name." % self.__class__.__name__)
- self.name = unicode(self.name) # Force unicode.
- if not self.slug:
- raise ValueError("%s must have a slug." % self.__class__.__name__)
- self.tab_group = tab_group
- self.request = request
- if request:
- self._allowed = self.allowed(request)
- self._enabled = self.enabled(request)
-
- def __repr__(self):
- return "<%s: %s>" % (self.__class__.__name__, self.slug)
-
- def is_active(self):
- """ Method to access whether or not this tab is the active tab. """
- if self._active is None:
- self.tab_group._set_active_tab()
- return self._active
-
- @property
- def load(self):
- load_preloaded = self.preload or self.is_active()
- return load_preloaded and self._allowed and self._enabled
-
- @property
- def data(self):
- if getattr(self, "_data", None) is None:
- self._data = self.get_context_data(self.request)
- return self._data
-
- @property
- def data_loaded(self):
- return getattr(self, "_data", None) is not None
-
- def render(self):
- """
- Renders the tab to HTML using the
- :meth:`~horizon.tabs.Tab.get_context_data` method and
- the :meth:`~horizon.tabs.Tab.get_template_name` method.
-
- If :attr:`~horizon.tabs.Tab.preload` is ``False`` and ``force_load``
- is not ``True``, or
- either :meth:`~horizon.tabs.Tab.allowed` or
- :meth:`~horizon.tabs.Tab.enabled` returns ``False`` this method will
- return an empty string.
- """
- if not self.load:
- return ''
- try:
- context = self.data
- except exceptions.Http302:
- raise
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- raise TemplateSyntaxError, exc_value, exc_traceback
- return render_to_string(self.get_template_name(self.request), context)
-
- def get_id(self):
- """
- Returns the id for this tab. Defaults to
- ``"{{ tab_group.slug }}__{{ tab.slug }}"``.
- """
- return SEPARATOR.join([self.tab_group.slug, self.slug])
-
- def get_query_string(self):
- return "=".join((self.tab_group.param_name, self.get_id()))
-
- def get_default_classes(self):
- """
- Returns a list of the default classes for the tab. Defaults to
- and empty list (``[]``), however additional classes may be added
- depending on the state of the tab as follows:
-
- If the tab is the active tab for the tab group, in which
- the class ``"active"`` will be added.
-
- If the tab is not enabled, the classes the class ``"disabled"``
- will be added.
- """
- default_classes = super(Tab, self).get_default_classes()
- if self.is_active():
- default_classes.extend(CSS_ACTIVE_TAB_CLASSES)
- if not self._enabled:
- default_classes.extend(CSS_DISABLED_TAB_CLASSES)
- return default_classes
-
- def get_template_name(self, request):
- """
- Returns the name of the template to be used for rendering this tab.
-
- By default it returns the value of the ``template_name`` attribute
- on the ``Tab`` class.
- """
- if not hasattr(self, "template_name"):
- raise AttributeError("%s must have a template_name attribute or "
- "override the get_template_name method."
- % self.__class__.__name__)
- return self.template_name
-
- def get_context_data(self, request):
- """
- This method should return a dictionary of context data used to render
- the tab. Required.
- """
- raise NotImplementedError("%s needs to define a get_context_data "
- "method." % self.__class__.__name__)
-
- def enabled(self, request):
- """
- Determines whether or not the tab should be accessible
- (e.g. be rendered into the HTML on load and respond to a click event).
-
- If a tab returns ``False`` from ``enabled`` it will ignore the value
- of ``preload`` and only render the HTML of the tab after being clicked.
-
- The default behavior is to return ``True`` for all cases.
- """
- return True
-
- def allowed(self, request):
- """
- Determines whether or not the tab is displayed.
-
- Tab instances can override this method to specify conditions under
- which this tab should not be shown at all by returning ``False``.
-
- The default behavior is to return ``True`` for all cases.
- """
- return True
-
-
-class TableTab(Tab):
- """
- A :class:`~horizon.tabs.Tab` class which knows how to deal with
- :class:`~horizon.tables.DataTable` classes rendered inside of it.
-
- This distinct class is required due to the complexity involved in handling
- both dynamic tab loading, dynamic table updating and table actions all
- within one view.
-
- .. attribute:: table_classes
-
- An iterable containing the :class:`~horizon.tables.DataTable` classes
- which this tab will contain. Equivalent to the
- :attr:`~horizon.tables.MultiTableView.table_classes` attribute on
- :class:`~horizon.tables.MultiTableView`. For each table class you
- need to define a corresponding ``get_{{ table_name }}_data`` method
- as with :class:`~horizon.tables.MultiTableView`.
- """
- table_classes = None
-
- def __init__(self, tab_group, request):
- super(TableTab, self).__init__(tab_group, request)
- if not self.table_classes:
- class_name = self.__class__.__name__
- raise NotImplementedError("You must define a table_class "
- "attribute on %s" % class_name)
- # Instantiate our table classes but don't assign data yet
- table_instances = [(table._meta.name,
- table(request, **tab_group.kwargs))
- for table in self.table_classes]
- self._tables = SortedDict(table_instances)
- self._table_data_loaded = False
-
- def load_table_data(self):
- """
- Calls the ``get_{{ table_name }}_data`` methods for each table class
- and sets the data on the tables.
- """
- # We only want the data to be loaded once, so we track if we have...
- if not self._table_data_loaded:
- for table_name, table in self._tables.items():
- # Fetch the data function.
- func_name = "get_%s_data" % table_name
- data_func = getattr(self, func_name, None)
- if data_func is None:
- cls_name = self.__class__.__name__
- raise NotImplementedError("You must define a %s method "
- "on %s." % (func_name, cls_name))
- # Load the data.
- table.data = data_func()
- table._meta.has_more_data = self.has_more_data(table)
- # Mark our data as loaded so we don't run the loaders again.
- self._table_data_loaded = True
-
- def get_context_data(self, request):
- """
- Adds a ``{{ table_name }}_table`` item to the context for each table
- in the :attr:`~horizon.tabs.TableTab.table_classes` attribute.
-
- If only one table class is provided, a shortcut ``table`` context
- variable is also added containing the single table.
- """
- context = {}
- # If the data hasn't been manually loaded before now,
- # make certain it's loaded before setting the context.
- self.load_table_data()
- for table_name, table in self._tables.items():
- # If there's only one table class, add a shortcut name as well.
- if len(self.table_classes) == 1:
- context["table"] = table
- context["%s_table" % table_name] = table
- return context
-
- def has_more_data(self, table):
- return False
diff --git a/horizon/tabs/views.py b/horizon/tabs/views.py
deleted file mode 100644
index cc683b92..00000000
--- a/horizon/tabs/views.py
+++ /dev/null
@@ -1,141 +0,0 @@
-from django import http
-from django.views import generic
-
-from horizon import exceptions
-from horizon import tables
-from horizon.tabs.base import TableTab
-
-
-class TabView(generic.TemplateView):
- """
- A generic class-based view for displaying a :class:`horizon.tabs.TabGroup`.
-
- This view handles selecting specific tabs and deals with AJAX requests
- gracefully.
-
- .. attribute:: tab_group_class
-
- The only required attribute for ``TabView``. It should be a class which
- inherits from :class:`horizon.tabs.TabGroup`.
- """
- tab_group_class = None
- _tab_group = None
-
- def __init__(self):
- if not self.tab_group_class:
- raise AttributeError("You must set the tab_group_class attribute "
- "on %s." % self.__class__.__name__)
-
- def get_tabs(self, request, **kwargs):
- """ Returns the initialized tab group for this view. """
- if self._tab_group is None:
- self._tab_group = self.tab_group_class(request, **kwargs)
- return self._tab_group
-
- def get_context_data(self, **kwargs):
- """ Adds the ``tab_group`` variable to the context data. """
- context = super(TabView, self).get_context_data(**kwargs)
- try:
- tab_group = self.get_tabs(self.request, **kwargs)
- context["tab_group"] = tab_group
- # Make sure our data is pre-loaded to capture errors.
- context["tab_group"].load_tab_data()
- except:
- exceptions.handle(self.request)
- return context
-
- def handle_tabbed_response(self, tab_group, context):
- """
- Sends back an AJAX-appropriate response for the tab group if
- required, otherwise renders the response as normal.
- """
- if self.request.is_ajax():
- if tab_group.selected:
- return http.HttpResponse(tab_group.selected.render())
- else:
- return http.HttpResponse(tab_group.render())
- return self.render_to_response(context)
-
- def get(self, request, *args, **kwargs):
- context = self.get_context_data(**kwargs)
- return self.handle_tabbed_response(context["tab_group"], context)
-
- def render_to_response(self, *args, **kwargs):
- response = super(TabView, self).render_to_response(*args, **kwargs)
- # Because Django's TemplateView uses the TemplateResponse class
- # to provide deferred rendering (which is usually helpful), if
- # a tab group raises an Http302 redirect (from exceptions.handle for
- # example) the exception is actually raised *after* the final pass
- # of the exception-handling middleware.
- response.render()
- return response
-
-
-class TabbedTableView(tables.MultiTableMixin, TabView):
- def __init__(self, *args, **kwargs):
- super(TabbedTableView, self).__init__(*args, **kwargs)
- self.table_classes = []
- self._table_dict = {}
-
- def load_tabs(self):
- """
- Loads the tab group, and compiles the table instances for each
- table attached to any :class:`horizon.tabs.TableTab` instances on
- the tab group. This step is necessary before processing any
- tab or table actions.
- """
- tab_group = self.get_tabs(self.request, **self.kwargs)
- tabs = tab_group.get_tabs()
- for tab in [t for t in tabs if issubclass(t.__class__, TableTab)]:
- self.table_classes.extend(tab.table_classes)
- for table in tab._tables.values():
- self._table_dict[table._meta.name] = {'table': table,
- 'tab': tab}
-
- def get_tables(self):
- """ A no-op on this class. Tables are handled at the tab level. """
- # Override the base class implementation so that the MultiTableMixin
- # doesn't freak out. We do the processing at the TableTab level.
- return {}
-
- def handle_table(self, table_dict):
- """
- For the given dict containing a ``DataTable`` and a ``TableTab``
- instance, it loads the table data for that tab and calls the
- table's :meth:`~horizon.tables.DataTable.maybe_handle` method. The
- return value will be the result of ``maybe_handle``.
- """
- table = table_dict['table']
- tab = table_dict['tab']
- tab.load_table_data()
- table_name = table._meta.name
- tab._tables[table_name]._meta.has_more_data = self.has_more_data(table)
- handled = tab._tables[table_name].maybe_handle()
- return handled
-
- def get(self, request, *args, **kwargs):
- self.load_tabs()
- # Gather our table instances. It's important that they're the
- # actual instances and not the classes!
- table_instances = [t['table'] for t in self._table_dict.values()]
- # Early out before any tab or table data is loaded
- for table in table_instances:
- preempted = table.maybe_preempt()
- if preempted:
- return preempted
-
- # If we have an action, determine if it belongs to one of our tables.
- # We don't iterate through all of the tables' maybes_handle
- # methods; just jump to the one that's got the matching name.
- table_name, action, obj_id = tables.DataTable.check_handler(request)
- if table_name in self._table_dict:
- handled = self.handle_table(self._table_dict[table_name])
- if handled:
- return handled
-
- context = self.get_context_data(**kwargs)
- return self.handle_tabbed_response(context["tab_group"], context)
-
- def post(self, request, *args, **kwargs):
- # GET and POST handling are the same
- return self.get(request, *args, **kwargs)
diff --git a/horizon/templates/_header.html b/horizon/templates/_header.html
deleted file mode 100644
index 76e99651..00000000
--- a/horizon/templates/_header.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{% load i18n %}
-{% load url from future %}
-<div id="user_info" class="pull-right">
- <span>{% trans "Logged in as" %}: {{ request.user.username }}</span>
- {% if HORIZON_CONFIG.help_url %}
- <a href="{{ HORIZON_CONFIG.help_url }}" target="_new">{% trans "Help" %}</a>
- {% endif %}
- <a href="{% url 'logout' %}">{% trans "Sign Out" %}</a>
-</div>
diff --git a/horizon/templates/_stylesheets.html b/horizon/templates/_stylesheets.html
deleted file mode 100644
index 7b3b3e40..00000000
--- a/horizon/templates/_stylesheets.html
+++ /dev/null
@@ -1 +0,0 @@
-{% comment %} This file is a placeholder for project overrides. {% endcomment %}
diff --git a/horizon/templates/auth/_login.html b/horizon/templates/auth/_login.html
deleted file mode 100644
index d244eb27..00000000
--- a/horizon/templates/auth/_login.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block modal-header %}{% trans "Log In" %}{% endblock %}
-{% block modal_class %}login {% if hide %}modal hide{% endif %}{% endblock %}
-
-{% block form_action %}{% url 'login' %}{% endblock %}
-{% block autocomplete %}{{ HORIZON_CONFIG.password_autocomplete }}{% endblock %}
-
-{% block modal-body %}
- <fieldset>
- {% if request.user.is_authenticated and 'next' in request.GET %}
- <div class="control-group clearfix error">
- <span class="help-inline"><p>{% trans "You don't have permissions to access:" %}</p>
- <p><b>{{ request.GET.next }}</b></p>
- <p>{% trans "Login as different user or go back to" %}
- <a href="{% url 'horizon:user_home' %}">{% trans "home page" %}</a></p>
- </span>
- </div>
- {% endif %}
- {% if next %}<input type="hidden" name="{{ redirect_field_name }}" value="{{ next }}" />{% endif %}
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-{% endblock %}
-
-{% block modal-footer %}
- <button type="submit" class="btn btn-primary pull-right">{% trans "Sign In" %}</button>
-{% endblock %}
diff --git a/horizon/templates/auth/login.html b/horizon/templates/auth/login.html
deleted file mode 100644
index 6fa7746b..00000000
--- a/horizon/templates/auth/login.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{% extends "base.html" %}
-{% load i18n %}
-
-{% block title %}{% trans "Login" %}{% endblock %}
-
-{% block body_id %}splash{% endblock %}
-
-{% block content %}
- {% include 'auth/_login.html' %}
-{% endblock %}
diff --git a/horizon/templates/base.html b/horizon/templates/base.html
deleted file mode 100644
index e7e59384..00000000
--- a/horizon/templates/base.html
+++ /dev/null
@@ -1,38 +0,0 @@
-{% load branding i18n %}
-<!DOCTYPE html>
-<html>
- <head>
- <meta content='text/html; charset=utf-8' http-equiv='Content-Type' />
- <title>{% block title %}{% endblock %} - {% site_branding %}</title>
- {% comment %} Load CSS sheets before Javascript {% endcomment %}
- {% block css %}
- {% include "_stylesheets.html" %}
- {% endblock %}
- {% include "horizon/_conf.html" %}
- {% include "horizon/client_side/_script_loader.html" %}
- </head>
- <body id="{% block body_id %}{% endblock %}">
- {% block content %}
- <div id="container">
- {% block sidebar %}
- {% include 'horizon/common/_sidebar.html' %}
- {% endblock %}
- <div id='main_content'>
- <div class='topbar'>
- {% include "_header.html" %}
- {% block page_header %}{% endblock %}
- </div>
- {% include "horizon/_messages.html" %}
- {% block main %}{% endblock %}
- </div>
- </div>
- {% endblock %}
- <div id="footer">
- {% block footer %}{% endblock %}
- </div>
- {% block js %}
- {% include "horizon/_scripts.html" %}
- {% endblock %}
- <div id="modal_wrapper" />
- </body>
-</html>
diff --git a/horizon/templates/horizon/_conf.html b/horizon/templates/horizon/_conf.html
deleted file mode 100644
index d577f1f7..00000000
--- a/horizon/templates/horizon/_conf.html
+++ /dev/null
@@ -1,21 +0,0 @@
-{% load compress %}
-
-{% compress js %}
-<script src='{{ STATIC_URL }}horizon/js/horizon.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.conf.js' type='text/javascript' charset='utf-8'></script>
-<script type='text/javascript' charset='utf-8'>
-/* Storage for backend configuration variables which the frontend
- * should be aware of.
- */
-horizon.conf.debug = {{ debug|yesno:"true,false" }};
-horizon.conf.static_url = "{{ STATIC_URL }}";
-horizon.conf.ajax = {
- queue_limit: {{ HORIZON_CONFIG.ajax_queue_limit|default:"null" }}
-};
-horizon.conf.auto_fade_alerts = {
- delay: {{ HORIZON_CONFIG.auto_fade_alerts.delay|default:"3000" }},
- fade_duration: {{ HORIZON_CONFIG.auto_fade_alerts.fade_duration|default:"1500" }},
- types: {{ HORIZON_CONFIG.auto_fade_alerts.types|default:"[]"|safe }}
-};
-</script>
-{% endcompress %}
diff --git a/horizon/templates/horizon/_messages.html b/horizon/templates/horizon/_messages.html
deleted file mode 100644
index b8a80b53..00000000
--- a/horizon/templates/horizon/_messages.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{% load i18n %}
-<div class="messages">
-{% for message in messages %}
- {% if "info" in message.tags %}
- <div class="alert alert-block alert-info fade in">
- <a class="close" data-dismiss="alert" href="#">&times;</a>
- <p><strong>{% trans "Info: " %}</strong>{{ message }}</p>
- </div>
- {% endif %}
- {% if "warning" in message.tags %}
- <div class="alert alert-block alert-warning fade in">
- <a class="close" data-dismiss="alert" href="#">&times;</a>
- <p><strong>{% trans "Warning: " %}</strong>{{ message }}</p>
- </div>
- {% endif %}
- {% if "success" in message.tags %}
- <div class="alert alert-block alert-success fade in">
- <a class="close" data-dismiss="alert" href="#">&times;</a>
- <p><strong>{% trans "Success: " %}</strong>{{ message }}</p>
- </div>
- {% endif %}
- {% if "error" in message.tags %}
- <div class="alert alert-block alert-error fade in">
- <a class="close" data-dismiss="alert" href="#">&times;</a>
- <p><strong>{% trans "Error: " %}</strong>{{ message }}</p>
- </div>
- {% endif %}
-{% endfor %}
-</div>
diff --git a/horizon/templates/horizon/_nav_list.html b/horizon/templates/horizon/_nav_list.html
deleted file mode 100644
index f300be27..00000000
--- a/horizon/templates/horizon/_nav_list.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% load horizon i18n %}
-
-<div class='clearfix'>
- <ul class="nav nav-tabs">
- {% for component in components %}
- {% if user|has_permissions:component %}
- <li{% if current.slug == component.slug %} class="active"{% endif %}>
- <a href="{{ component.get_absolute_url }}" tabindex='1'>{{ component.name }}</a>
- </li>
- {% endif %}
- {% endfor %}
- </ul>
-</div>
diff --git a/horizon/templates/horizon/_scripts.html b/horizon/templates/horizon/_scripts.html
deleted file mode 100644
index b3edd204..00000000
--- a/horizon/templates/horizon/_scripts.html
+++ /dev/null
@@ -1,52 +0,0 @@
-{% load compress %}
-{% load url from future %}
-
-{% comment %} Django's JavaScript i18n Implementation {% endcomment %}
-<script type="text/javascript" src="{% url 'horizon:jsi18n' 'horizon' %}"></script>
-
-{% comment %} Compress jQuery, Plugins, Bootstrap, Hogan.js and Horizon-specific JS. {% endcomment %}
-{% compress js %}
-<script src='{{ STATIC_URL }}horizon/lib/jquery/jquery.min.js' type='text/javascript' charset="utf-8"></script>
-<script src='{{ STATIC_URL }}horizon/lib/jquery/jquery.cookie.js' type='text/javascript' charset="utf-8"></script>
-<script src='{{ STATIC_URL }}horizon/lib/jquery/jquery.quicksearch.js' type='text/javascript' charset="utf-8"></script>
-<script src="{{ STATIC_URL }}horizon/lib/jquery/jquery.table-sorter.js" type="text/javascript" charset="utf-8"></script>
-<script src="{{ STATIC_URL }}horizon/lib/spin.js" type="text/javascript" charset="utf-8"></script>
-<script src="{{ STATIC_URL }}horizon/lib/spin.jquery.js" type="text/javascript" charset="utf-8"></script>
-<script src='{{ STATIC_URL }}horizon/lib/json2.js' type='text/javascript' charset="utf-8"></script>
-<script src="{{ STATIC_URL }}horizon/lib/underscore/underscore-min.js" type="text/javascript" charset="utf-8"></script>
-<script src="{{ STATIC_URL }}horizon/lib/jquery/jquery-ui-1.9.2.custom.min.js" type="text/javascript" charset="utf-8"></script>
-
-<script src="{{ STATIC_URL }}horizon/lib/d3.v3.min.js" type="text/javascript" charset="utf-8"></script>
-
-<script src="{{ STATIC_URL }}bootstrap/js/bootstrap.min.js" type="text/javascript" charset="utf-8"></script>
-<script src='{{ STATIC_URL }}bootstrap/js/bootstrap-datepicker.js' type='text/javascript' charset='utf-8'></script>
-
-<script src="{{ STATIC_URL }}horizon/lib/hogan-2.0.0.js" type="text/javascript" charset='utf-8'></script>
-
-<script src='{{ STATIC_URL }}horizon/js/horizon.communication.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.cookies.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.forms.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.instances.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.messages.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.modals.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.quota.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.tables.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.tabs.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.templates.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.users.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.utils.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.projects.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.networktopology.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.d3piechart.js' type='text/javascript' charset='utf-8'></script>
-<script src='{{ STATIC_URL }}horizon/js/horizon.heattop.js' type='text/javascript' charset='utf-8'></script>
-{% block custom_js_files %}{% endblock %}
-{% endcompress %}
-
-{% comment %} Client-side Templates (These should *not* be inside the "compress" tag.) {% endcomment %}
-{% include "horizon/client_side/templates.html" %}
-
-{% comment %}Go!{% endcomment %}
-<script type='text/javascript' charset='utf-8'>
- // Call init on DOM ready.
- $(document).ready(horizon.init);
-</script>
diff --git a/horizon/templates/horizon/_subnav_list.html b/horizon/templates/horizon/_subnav_list.html
deleted file mode 100644
index 273589ad..00000000
--- a/horizon/templates/horizon/_subnav_list.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% load horizon %}
-
-{% for heading, panels in components.iteritems %}
- {% with panels|has_permissions_on_list:user as filtered_panels %}
- {% if filtered_panels %}
- {% if heading %}<h4>{{ heading }}</h4>{% endif %}
- <ul class="main_nav">
- {% for panel in filtered_panels %}
- <li>
- <a href="{{ panel.get_absolute_url }}" {% if current == panel.slug %}class="active"{% endif %} tabindex='1'>{{ panel.name }}</a>
- </li>
- {% endfor %}
- </ul>
- {% endif %}
- {% endwith %}
-{% endfor %}
diff --git a/horizon/templates/horizon/client_side/_alert_message.html b/horizon/templates/horizon/client_side/_alert_message.html
deleted file mode 100644
index 6a5fea20..00000000
--- a/horizon/templates/horizon/client_side/_alert_message.html
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends "horizon/client_side/template.html" %}
-{% load horizon %}
-
-{% block id %}alert_message_template{% endblock %}
-
-{% block template %}
-{% jstemplate %}
-<div class="alert alert-block fade in alert-[[type]]">
- <a class="close" data-dismiss="alert" href="#">&times;</a>
- <p>
- <strong>[[type_capitalized]]: </strong>
- [[#safe]]
- [[[message]]]
- [[/safe]]
- [[^safe]]
- [[message]]
- [[/safe]]
- </p>
-</div>
-{% endjstemplate %}
-{% endblock %}
diff --git a/horizon/templates/horizon/client_side/_loading.html b/horizon/templates/horizon/client_side/_loading.html
deleted file mode 100644
index c4f6c967..00000000
--- a/horizon/templates/horizon/client_side/_loading.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends "horizon/client_side/template.html" %}
-{% load i18n horizon %}
-
-{% block id %}spinner-modal{% endblock %}
-
-{% block template %}
-{% jstemplate %}
-<div class="modal loading hide">
- <p>[[text]]&hellip;</p>
-</div>
-{% endjstemplate %}
-{% endblock %}
diff --git a/horizon/templates/horizon/client_side/_modal.html b/horizon/templates/horizon/client_side/_modal.html
deleted file mode 100644
index 9922eeb5..00000000
--- a/horizon/templates/horizon/client_side/_modal.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends "horizon/client_side/template.html" %}
-{% load horizon %}
-
-{% block id %}modal_template{% endblock %}
-
-{% block template %}
-{% jstemplate %}
-<div class="modal hide">
- <div class='modal-header'>
- <a class='close' data-dismiss='modal'>&times;</a>
- <h3>[[title]]</h3>
- </div>
- <div class='modal-body'>
- [[body]]
- </div>
- <div class='modal-footer'>
- <a href='#' class='btn btn-primary'>[[confirm]]</a>
- <a href='#' class='btn cancel' data-dismiss='modal'>[[cancel]]</a>
- </div>
-</div>
-{% endjstemplate %}
-{% endblock %}
diff --git a/horizon/templates/horizon/client_side/_modal_chart.html b/horizon/templates/horizon/client_side/_modal_chart.html
deleted file mode 100644
index e26a7d4d..00000000
--- a/horizon/templates/horizon/client_side/_modal_chart.html
+++ /dev/null
@@ -1,19 +0,0 @@
-{% extends "horizon/client_side/template.html" %}
-{% load horizon %}
-
-{% block id %}modal_chart_template{% endblock %}
-
-{% block template %}
-{% jstemplate %}
-<div class="[[classes]]" style="top: 80px; display: block;">
- <ul id="interval_selector">
- <li><a href="#" data-interval="12h">12h</a></li>
- <li><a href="#" data-interval="24h">24h</a></li>
- <li class="active"><a href="#" data-interval="1w">1w</a></li>
- <li><a href="#" data-interval="1m">1m</a></li>
- <li><a href="#" data-interval="1y">1y</a></li>
- </ul>
- <div id="modal_chart"></div>
-</div>
-{% endjstemplate %}
-{% endblock %}
diff --git a/horizon/templates/horizon/client_side/_project_user.html b/horizon/templates/horizon/client_side/_project_user.html
deleted file mode 100644
index a621a892..00000000
--- a/horizon/templates/horizon/client_side/_project_user.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/client_side/template.html" %}
-{% load horizon %}
-
-{% block id %}project_user_template{% endblock %}
-
-{% block template %}
-{% jstemplate %}
-<ul class="nav nav-pills btn-group">
- <li class="member" data-user-id="[[user_id]]">
- <span class="user_name">[[user_name]]</span>
- </li>
- <li class="active"><a class="btn btn-primary" href="#add_remove">[[text]]</a></li>
- <li class="dropdown role_options">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">
- <span class="roles_display">Roles</span>
- <b class="caret"></b>
- </a>
- <ul class="dropdown-menu role_dropdown clearfix">
- [[#roles]]
- <li data-role-id="[[role_id]]"><i class="icon-ok"></i> [[role_name]]</li>
- [[/roles]]
- </ul>
- </li>
-</ul>
-{% endjstemplate %}
-{% endblock %}
diff --git a/horizon/templates/horizon/client_side/_script_loader.html b/horizon/templates/horizon/client_side/_script_loader.html
deleted file mode 100644
index 0d72ab1b..00000000
--- a/horizon/templates/horizon/client_side/_script_loader.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<script type="text/javascript" charset="utf-8">
- /*
- Added so that we can append Horizon scoped JS events to
- the DOM load events without running in to the "horizon"
- name-space not currently being defined since we load the
- scripts at the bottom of the page.
- */
- var addHorizonLoadEvent = function(func) {
- var old_onload = window.onload;
-
- if (typeof window.onload != 'function') {
- window.onload = func;
- } else {
- window.onload = function() {
- old_onload();
- func();
- }
- }
- }
-</script>
diff --git a/horizon/templates/horizon/client_side/_table_row.html b/horizon/templates/horizon/client_side/_table_row.html
deleted file mode 100644
index 3f22e644..00000000
--- a/horizon/templates/horizon/client_side/_table_row.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{% extends "horizon/client_side/template.html" %}
-{% load horizon %}
-
-{% block id %}empty_row_template{% endblock %}
-
-{% block template %}
-{% jstemplate %}
-<tr class="odd empty"><td colspan="[[colspan]]">No items to display.</td></tr>
-{% endjstemplate %}
-{% endblock %} \ No newline at end of file
diff --git a/horizon/templates/horizon/client_side/template.html b/horizon/templates/horizon/client_side/template.html
deleted file mode 100644
index 1f30fb32..00000000
--- a/horizon/templates/horizon/client_side/template.html
+++ /dev/null
@@ -1 +0,0 @@
-<script type="text/html" id="{% block id %}{% endblock %}">{% block template %}{% endblock %}</script>
diff --git a/horizon/templates/horizon/client_side/templates.html b/horizon/templates/horizon/client_side/templates.html
deleted file mode 100644
index eeafe83d..00000000
--- a/horizon/templates/horizon/client_side/templates.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{% include "horizon/client_side/_modal.html" %}
-{% include "horizon/client_side/_modal_chart.html" %}
-{% include "horizon/client_side/_table_row.html" %}
-{% include "horizon/client_side/_alert_message.html" %}
-{% include "horizon/client_side/_loading.html" %}
-{% include "horizon/client_side/_project_user.html" %}
diff --git a/horizon/templates/horizon/common/_breadcrumb.html b/horizon/templates/horizon/common/_breadcrumb.html
deleted file mode 100644
index df68b583..00000000
--- a/horizon/templates/horizon/common/_breadcrumb.html
+++ /dev/null
@@ -1,20 +0,0 @@
-{% load url from future %}
-{% load i18n %}
-{% with subfolders=breadcrumb.get_subfolders %}
-<ul class="breadcrumb">
- <li>
- Folder Path: <a href="{% url 'breadcrumb.url' breadcrumb.root|add:'/' %}">{{ breadcrumb.root }}</a> <span class="divider">/</span>
- </li>
- {% for subfolder, path in subfolders %}
- <li>
- {% if not forloop.last %}
- <a href="{% url 'breadcrumb.url' breadcrumb.root|add:'/' path %}">
- {% endif %}
- {{ subfolder }}
- {% if not forloop.last %}
- </a> <span class="divider">/</span>
- {% endif %}
- </li>
- {% endfor %}
-</ul>
-{% endwith %}
diff --git a/horizon/templates/horizon/common/_data_table.html b/horizon/templates/horizon/common/_data_table.html
deleted file mode 100644
index d8a26370..00000000
--- a/horizon/templates/horizon/common/_data_table.html
+++ /dev/null
@@ -1,78 +0,0 @@
-{% load i18n %}
-{% with table.needs_form_wrapper as needs_form_wrapper %}
-<div class="table_wrapper">
- {% if needs_form_wrapper %}<form action="{{ table.get_absolute_url }}" method="POST">{% csrf_token %}{% endif %}
- {% with columns=table.get_columns rows=table.get_rows %}
-{% block table %}
- <table id="{{ table.name }}" class="table table-bordered table-striped datatable">
- <thead>
- {% block table_caption %}
- <tr class='table_caption'>
- <th class='table_header' colspan='{{ columns|length }}'>
- <h3 class='table_title'>{{ table }}</h3>
- {{ table.render_table_actions }}
- </th>
- </tr>
- {% endblock table_caption %}
- {% block table_breadcrumb %}
- {% if table.breadcrumb %}
- <tr>
- <td class="breadcrumb_td" colspan="{{ table.get_columns|length }}">
- {{ table.breadcrumb.render }}
- </td>
- </tr>
- {% endif %}
- {% endblock table_breadcrumb %}
- {% block table_columns %}
- {% if not table.is_browser_table %}
- <tr>
- {% for column in columns %}
- <th {{ column.attr_string|safe }}>{{ column }}</th>
- {% endfor %}
- </tr>
- {% endif %}
- {% endblock table_columns %}
- </thead>
- {% block table_body %}
- <tbody>
- {% for row in rows %}
- {{ row.render }}
- {% empty %}
- <tr class="{% cycle 'odd' 'even' %} empty">
- <td colspan="{{ table.get_columns|length }}">{{ table.get_empty_message }}</td>
- </tr>
- {% endfor %}
- </tbody>
- {% endblock table_body %}
- {% block table_footer %}
- {% if table.footer %}
- <tfoot>
- {% if table.needs_summary_row %}
- <tr class="summation">
- {% for column in columns %}
- {% if forloop.first %}
- <td>{% trans "Summary" %}</td>
- {% else %}
- <td>{{ column.get_summation|default_if_none:"&ndash;"}}</td>
- {% endif %}
- {% endfor %}
- </tr>
- {% endif %}
- <tr>
- <td colspan="{{ table.get_columns|length }}">
- <span class="table_count">{% blocktrans count counter=rows|length %}Displaying {{ counter }} item{% plural %}Displaying {{ counter }} items{% endblocktrans %}</span>
- {% if table.has_more_data %}
- <span class="spacer">|</span>
- <a href="?{{ table.get_pagination_string }}">More&nbsp;&raquo;</a>
- {% endif %}
- </td>
- </tr>
- </tfoot>
- {% endif %}
- {% endblock table_footer %}
- </table>
-{% endblock table %}
- {% endwith %}
- {% if needs_form_wrapper %}</form>{% endif %}
-</div>
-{% endwith %}
diff --git a/horizon/templates/horizon/common/_data_table_row.html b/horizon/templates/horizon/common/_data_table_row.html
deleted file mode 100644
index 3e0c8b0f..00000000
--- a/horizon/templates/horizon/common/_data_table_row.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<tr{{ row.attr_string|safe }}>
- {% for cell in row %}<td{{ cell.attr_string|safe }}>{{ cell.value }}</td>{% endfor %}
-</tr>
diff --git a/horizon/templates/horizon/common/_data_table_row_action.html b/horizon/templates/horizon/common/_data_table_row_action.html
deleted file mode 100644
index d766fb31..00000000
--- a/horizon/templates/horizon/common/_data_table_row_action.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% if action.method != "GET" %}
- <button {{ action.attr_string|safe }} name="action" value="{{ action.table.name }}__{{ action.name }}__{{ row_id }}" type="submit">{{ action.verbose_name }}</button>
-{% else %}
- <a href='{{ action.bound_url }}' {{ action.attr_string|safe }}>{{ action.verbose_name }}</a>
-{% endif %}
diff --git a/horizon/templates/horizon/common/_data_table_row_actions.html b/horizon/templates/horizon/common/_data_table_row_actions.html
deleted file mode 100644
index 8619da17..00000000
--- a/horizon/templates/horizon/common/_data_table_row_actions.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{% load horizon i18n %}
-
-{% spaceless %} {# This makes sure whitespace doesn't affect positioning for dropdown. #}
-{% if row_actions|length > 1 %}
-<div class="btn-group">
- {% for action in row_actions %}
- {% if forloop.first %}
- {% include "horizon/common/_data_table_row_action.html" %}
- <a class="btn btn-small dropdown-toggle" data-toggle="dropdown" href="#">
- {% trans "More" %}
- <span class="caret"></span>
- </a>
- <ul class="dropdown-menu row_actions clearfix">
- {% else %}
- <li class="clearfix">
- {% include "horizon/common/_data_table_row_action.html" %}
- </li>
- {% endif %}
- {% if forloop.last %}
- </ul>
- {% endif %}
- {% endfor %}
-</div>
-{% endif %}
-{% if row_actions|length == 1%}
- {% for action in row_actions %}
- {% include "horizon/common/_data_table_row_action.html" %}
- {% endfor %}
-{% endif %}
-{% endspaceless %}
diff --git a/horizon/templates/horizon/common/_data_table_table_actions.html b/horizon/templates/horizon/common/_data_table_table_actions.html
deleted file mode 100644
index 44b43f67..00000000
--- a/horizon/templates/horizon/common/_data_table_table_actions.html
+++ /dev/null
@@ -1,28 +0,0 @@
-{% load i18n %}
-<div class="table_actions clearfix">
-{% block table_filter %}
- {% if filter.filter_type == 'fixed' %}
- <div class="table_filter btn-group" data-toggle="buttons-radio">
- {% for button in filter.fixed_buttons %}
- <button name="{{ filter.get_param_name }}" type="submit" value="{{ button.value }}" class="btn btn-small{% ifequal button.value filter.filter_string %} active{% endifequal %}">{% if button.icon %}<i class="{{ button.icon }}"></i> {% endif %}{{ button.text }}{% if button.count >= 0 %} ({{ button.count }}){% endif %}</button>
- {% endfor %}
- </div>
- {% elif filter.filter_type == 'query' %}
- <div class="table_search">
- <input class="span3 example" value="{{ filter.filter_string|default:'' }}" type="text" name="{{ filter.get_param_name }}" />
- <button type="submit" {{ filter.attr_string|safe }}>{% trans "Filter" %}</button>
- </div>
- {% endif %}
-{% endblock table_filter %}
-{% block table_actions %}
- {% for action in table_actions %}
- {% if action != filter %}
- {% if action.method != "GET" %}
- <button {{ action.attr_string|safe }} name="action" value="{{ action.get_param_name }}" type="submit">{% if action.handles_multiple %}{{ action.verbose_name_plural }}{% else %}{{ action.verbose_name }}{% endif %}</button>
- {% else %}
- <a href='{{ action.get_link_url }}' title='{{ action.verbose_name }}' {{ action.attr_string|safe }}>{{ action.verbose_name }}</a>
- {% endif %}
- {% endif %}
- {% endfor %}
- </div>
-{% endblock table_actions %}
diff --git a/horizon/templates/horizon/common/_detail_table.html b/horizon/templates/horizon/common/_detail_table.html
deleted file mode 100644
index 99f86d42..00000000
--- a/horizon/templates/horizon/common/_detail_table.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ table.render }}
diff --git a/horizon/templates/horizon/common/_domain_page_header.html b/horizon/templates/horizon/common/_domain_page_header.html
deleted file mode 100644
index 63ab048c..00000000
--- a/horizon/templates/horizon/common/_domain_page_header.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% load i18n %}
-{% block page_header %}
- <div class='page-header'>
- <h2>
- {% if request.session.domain_context_name %}
- <em>{{ request.session.domain_context_name }}:</em>
- {% endif %}
- {{ title }}
- </h2>
- </div>
-{% endblock %}
diff --git a/horizon/templates/horizon/common/_form_fields.html b/horizon/templates/horizon/common/_form_fields.html
deleted file mode 100644
index 21a9abdf..00000000
--- a/horizon/templates/horizon/common/_form_fields.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% for hidden in form.hidden_fields %}
- {{ hidden }}
-{% endfor %}
-{% if form.non_field_errors %}
- <div class="alert alert-message alert-error">
- {{ form.non_field_errors }}
- </div>
-{% endif %}
-{% for field in form.visible_fields %}
- <div class="control-group form-field clearfix{% if field.errors %} error{% endif %}">
- {{ field.label_tag }}
- {% if field.errors %}
- {% for error in field.errors %}
- <span class="help-inline">{{ error }}</span>
- {% endfor %}
- {% endif %}
- <span class="help-block">{{ field.help_text }}</span>
- <div class="input">
- {{ field }}
- </div>
- </div>
-{% endfor %}
diff --git a/horizon/templates/horizon/common/_limit_summary.html b/horizon/templates/horizon/common/_limit_summary.html
deleted file mode 100644
index fe07766d..00000000
--- a/horizon/templates/horizon/common/_limit_summary.html
+++ /dev/null
@@ -1,39 +0,0 @@
-{% load i18n horizon humanize sizeformat %}
-
-<div class="quota-dynamic">
- <h3>{% trans "Limit Summary" %}</h3>
- <div class="d3_quota_bar">
- <div class="d3_pie_chart" data-used="{% widthratio usage.limits.totalInstancesUsed usage.limits.maxTotalInstances 100 %}"></div>
- <strong>{% trans "Instances" %} <br />
- {% blocktrans with used=usage.limits.totalInstancesUsed|intcomma available=usage.limits.maxTotalInstances|intcomma %}Used <span> {{ used }} </span> of <span> {{ available }} </span>{% endblocktrans %}
- </strong>
- </div>
-
- <div class="d3_quota_bar">
- <div class="d3_pie_chart" data-used="{% widthratio usage.limits.totalCoresUsed usage.limits.maxTotalCores 100 %}"></div>
- <strong>{% trans "VCPUs" %} <br />
- {% blocktrans with used=usage.limits.totalCoresUsed|intcomma available=usage.limits.maxTotalCores|intcomma %}Used <span> {{ used }} </span> of <span> {{ available }} </span>{% endblocktrans %}
- </strong>
- </div>
-
- <div class="d3_quota_bar">
- <div class="d3_pie_chart" data-used="{% widthratio usage.limits.totalRAMUsed usage.limits.maxTotalRAMSize 100 %}"></div>
- <strong>{% trans "RAM" %} <br />
- {% blocktrans with used=usage.limits.totalRAMUsed|intcomma available=usage.limits.maxTotalRAMSize|intcomma %}Used <span> {{ used }} MB </span> of <span> {{ available }} MB </span>{% endblocktrans %}
- </strong>
- </div>
-
- <div class="d3_quota_bar">
- <div class="d3_pie_chart" data-used="{% widthratio usage.limits.totalFloatingIpsUsed usage.limits.maxTotalFloatingIps 100 %}"></div>
- <strong>{% trans "Floating IPs" %} <br />
- {% blocktrans with used=usage.limits.totalFloatingIpsUsed|intcomma available=usage.limits.maxTotalFloatingIps|intcomma %}Used <span> {{ used }} </span> of <span> {{ available }} </span>{% endblocktrans %}
- </strong>
- </div>
-
- <div class="d3_quota_bar">
- <div class="d3_pie_chart" data-used="{% widthratio usage.limits.totalSecurityGroupsUsed usage.limits.maxSecurityGroups 100 %}"></div>
- <strong>{% trans "Security Groups" %} <br />
- {% blocktrans with used=usage.limits.totalSecurityGroupsUsed|intcomma available=usage.limits.maxSecurityGroups|intcomma%}Used <span> {{ used }} </span> of <span> {{ available }} </span>{% endblocktrans %}
- </strong>
- </div>
-</div>
diff --git a/horizon/templates/horizon/common/_modal.html b/horizon/templates/horizon/common/_modal.html
deleted file mode 100644
index 34863bf5..00000000
--- a/horizon/templates/horizon/common/_modal.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<div id="{% block modal_id %}{% endblock %}" class="{% block modal_class %}{% if hide %}modal hide{% else %}static_page{% endif %}{% endblock %}">
- <div class="modal-header">
- {% if hide %}<a href="#" class="close" data-dismiss="modal">&times;</a>{% endif %}
- <h3>{% block modal-header %}{% endblock %}</h3>
- </div>
- <div class="modal-body clearfix">
- {% block modal-body %}{% endblock %}
- </div>
- <div class="modal-footer">{% block modal-footer %}{% endblock %}</div>
-</div>
diff --git a/horizon/templates/horizon/common/_modal_form.html b/horizon/templates/horizon/common/_modal_form.html
deleted file mode 100644
index 8b56631d..00000000
--- a/horizon/templates/horizon/common/_modal_form.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<div id="{% block modal_id %}{% endblock %}" class="{% block modal_class %}{% if hide %}modal hide{% else %}static_page{% endif %}{% endblock %}">
- <div class="modal-header">
- {% if hide %}<a href="#" class="close" data-dismiss="modal">&times;</a>{% endif %}
- <h3>{% block modal-header %}{% endblock %}</h3>
- </div>
- {% if table %}
- <div class="modal-body">
- {{ table.render }}
- </div>
- <hr />
- {% endif %}
- <form id="{% block form_id %}{% endblock %}" autocomplete="{% block autocomplete %}{% endblock %}" class="{% block form_class %}{% endblock %}" action="{% block form_action %}{% endblock %}" method="{% block form-method %}POST{% endblock %}" {% if add_to_field %}data-add-to-field="{{ add_to_field }}"{% endif %} {% block form_attrs %}{% endblock %}>{% csrf_token %}
- <div class="modal-body clearfix">
- {% block modal-body %}
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
- {% endblock %}
- </div>
- <div class="modal-footer">{% block modal-footer %}{% endblock %}</div>
- </form>
-</div>
-{% block modal-js %}
-{% endblock %} \ No newline at end of file
diff --git a/horizon/templates/horizon/common/_modal_form_add_members.html b/horizon/templates/horizon/common/_modal_form_add_members.html
deleted file mode 100644
index fa7bf6d0..00000000
--- a/horizon/templates/horizon/common/_modal_form_add_members.html
+++ /dev/null
@@ -1,41 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-
-{% block modal-body %}
-<input type="hidden" id="hidden_redirect_back_to_home" name="redirect" value="{{redirect}}"/>
-{% endblock %}
-
-{% block modal-js %}
-<script type="text/javascript">
-<!--
- /* ensure the value of the action buttons also gets submitted */
- $(':button[name="action"]').click(function () {
- value = $(this).attr("value");
-
- $('<input>').attr({
- type: 'hidden',
- name: 'action',
- value: value,
- }).appendTo('form');
-
- var redirect = $('#hidden_redirect_back_to_home').val();
- $('<input>').attr({
- type: 'hidden',
- name: 'redirect',
- value: redirect,
- }).appendTo('form');
-
- return true;
- });
-
- /* add the correct ajax class for table footer links */
- $("tfoot a").addClass("ajax-modal");
-
- /* as you navigate around the more pages, they stack on top of each other
- make sure this stack gets cleaned up so there is only on*/
- hidden_modals = $("#modal_wrapper .modal.hide:not(:last-child)");
- hidden_modals.detach();
-
-//-->
-</script>
-{% endblock %} \ No newline at end of file
diff --git a/horizon/templates/horizon/common/_page_header.html b/horizon/templates/horizon/common/_page_header.html
deleted file mode 100644
index adeb06e6..00000000
--- a/horizon/templates/horizon/common/_page_header.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{% load i18n %}
-{% block page_header %}
- <div class='page-header'>
- <h2>{{ title }}</h2>
- </div>
-{% endblock %}
diff --git a/horizon/templates/horizon/common/_region_selector.html b/horizon/templates/horizon/common/_region_selector.html
deleted file mode 100644
index ef325200..00000000
--- a/horizon/templates/horizon/common/_region_selector.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% load url from future %}
-{% if regions.support %}
- <div id="region_switcher" class="dropdown switcher_bar" tabindex='1'>
- <a class="dropdown-toggle" data-toggle="dropdown" href="#region_switcher">
- {{ regions.current.name }}
- </a>
- <ul id="region_list" class="dropdown-menu">
- <li class='divider'></li>
- {% for region in regions.available %}
- {% if region.name != regions.current.name %}
- <li><a class="ajax-modal" href="{% url 'login' %}?region={{ region.endpoint|urlencode }}">{{ region.name }}</a></li>
- {% endif %}
- {% endfor %}
- </ul>
- </div>
-{% endif %}
diff --git a/horizon/templates/horizon/common/_resource_browser.html b/horizon/templates/horizon/common/_resource_browser.html
deleted file mode 100644
index 5caa4b88..00000000
--- a/horizon/templates/horizon/common/_resource_browser.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% load i18n %}
-<div id="browser_wrapper" class="pull-left">
- <div class="navigation_wrapper">
- {{ browser.navigation_table.render }}
- </div>
- <div class="content_wrapper">
- {{ browser.content_table.render }}
- </div>
- <div class="tfoot">
- <span class="navigation_table_count">{% blocktrans count nav_items=browser.navigation_table.data|length %}Displaying {{ nav_items }} item{% plural %}Displaying {{ nav_items }} items{% endblocktrans %}</span>
- <span class="content_table_count">{% blocktrans count content_items=browser.content_table.data|length %}Displaying {{ content_items }} item{% plural %}Displaying {{ content_items }} items{% endblocktrans %}</span>
- </div>
-</div>
diff --git a/horizon/templates/horizon/common/_sidebar.html b/horizon/templates/horizon/common/_sidebar.html
deleted file mode 100644
index b5367674..00000000
--- a/horizon/templates/horizon/common/_sidebar.html
+++ /dev/null
@@ -1,54 +0,0 @@
-{% load branding horizon i18n %}
-{% load url from future %}
-
-<div class='sidebar'>
- <h1 class="brand clearfix"><a href="{% url 'horizon:user_home' %}">{% site_branding %}</a></h1>
-
- {% horizon_main_nav %}
-
- {% if request.horizon.dashboard.supports_tenants %}
- <div id="tenant_switcher" class="dropdown switcher_bar" tabindex="1">
- {% with num_of_tenants=authorized_tenants|length %}
- {% if num_of_tenants > 1 %}
- <a class="dropdown-toggle" data-toggle="dropdown" href="#tenant_switcher">
- {% endif %}
- <h4>{% trans "Current Project" %}</h4>
- <h3>{{ request.user.tenant_name }}</h3>
- {% if num_of_tenants > 1 %}
- </a>
- {% endif %}
-
- {% if num_of_tenants > 1 %}
- <ul id="tenant_list" class="dropdown-menu">
- <li class='divider'></li>
- {% for tenant in authorized_tenants %}
- {% if tenant.enabled and tenant.id != request.user.tenant_id %}
- <li><a href="{% url 'switch_tenants' tenant.id %}?next={{ request.horizon.dashboard.get_absolute_url }}">{{ tenant.name }}</a></li>
- {% endif %}
- {% endfor %}
- </ul>
- {% endif %}
- {% endwith %}
- </div>
- {% endif %}
-
- {% with num_of_regions=request.user.available_services_regions|length %}
- {% if num_of_regions > 1 %}
- <div id="services_region_switcher" class="dropdown switcher_bar" tabindex="1">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#services_region_switcher">
- <h4>{% trans "Managing Region" %}</h4>
- <h3>{{ request.user.services_region }}</h3>
- </a>
-
- <ul id="services_regions_list" class="dropdown-menu">
- <li class='divider'></li>
- {% for region in request.user.available_services_regions %}
- <li><a href="{% url 'switch_services_region' region %}?next={{ request.horizon.panel.get_absolute_url }}">{{ region }}</a></li>
- {% endfor %}
- </ul>
- </div>
- {% endif %}
- {% endwith %}
-
- {% horizon_dashboard_nav %}
-</div>
diff --git a/horizon/templates/horizon/common/_sidebar_module.html b/horizon/templates/horizon/common/_sidebar_module.html
deleted file mode 100644
index 2b9739ce..00000000
--- a/horizon/templates/horizon/common/_sidebar_module.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{% for module in modules %}
- <h3>{{ module.title }}</h3>
-
- <ul class="sub_nav">
- {% for link in module.links %}
- <li><a {% if request.get_full_path == link.url %} class="active" {% endif %} href="{{ link.url }}">{{ link.text }}</a></li>
- {% endfor %}
- </ul>
-{% endfor %}
-
diff --git a/horizon/templates/horizon/common/_tab_group.html b/horizon/templates/horizon/common/_tab_group.html
deleted file mode 100644
index 89ca70ca..00000000
--- a/horizon/templates/horizon/common/_tab_group.html
+++ /dev/null
@@ -1,23 +0,0 @@
-{% with tab_group.get_tabs as tabs %}
-{% if tabs %}
-
- {# Tab Navigation #}
- <ul id="{{ tab_group.get_id }}" {{ tab_group.attr_string|safe }}>
- {% for tab in tabs %}
- <li {{ tab.attr_string|safe }}>
- <a href="?{{ tab_group.param_name}}={{ tab.get_id }}" data-toggle="tab" data-target="#{{ tab.get_id }}" data-loaded='{{ tab.load|yesno:"true,false" }}'>{{ tab.name }}</a>
- </li>
- {% endfor %}
- </ul>
-
- {# Tab Content #}
- <div class="tab-content">
- {% for tab in tabs %}
- <div id="{{ tab.get_id }}" class="tab-pane{% if tab.is_active %} active{% endif %}">
- {{ tab.render }}
- </div>
- {% endfor %}
- </div>
-
-{% endif %}
-{% endwith %}
diff --git a/horizon/templates/horizon/common/_usage_summary.html b/horizon/templates/horizon/common/_usage_summary.html
deleted file mode 100644
index 6b34d3ac..00000000
--- a/horizon/templates/horizon/common/_usage_summary.html
+++ /dev/null
@@ -1,20 +0,0 @@
-{% load i18n sizeformat %}
-
-<div class="usage_info_wrapper">
- <form action="" method="get" id="date_form" class="form-horizontal">
- <h3>{% trans "Select a period of time to query its usage" %}: </h3>
- <div class="datepicker">
- <span>{% trans "From" %}: {{ form.start }} </span>
- <span>{% trans "To" %}: {{ form.end }} </span>
- <button class="btn btn-small" type="submit">{% trans "Submit" %}</button>
- <small>{% trans "The date should be in YYYY-mm-dd format." %}</small>
- </div>
- </form>
-
- <p id="activity">
- <span><strong>{% trans "Active Instances" %}:</strong> {{ usage.summary.instances|default:'-' }}</span>
- <span><strong>{% trans "Active RAM" %}:</strong> {{ usage.summary.memory_mb|mbformat|default:'-' }}</span>
- <span><strong>{% trans "This Period's VCPU-Hours" %}:</strong> {{ usage.summary.vcpu_hours|floatformat:2|default:'-' }}</span>
- <span><strong>{% trans "This Period's GB-Hours" %}:</strong> {{ usage.summary.disk_gb_hours|floatformat:2|default:'-' }}</span>
- </p>
-</div>
diff --git a/horizon/templates/horizon/common/_workflow.html b/horizon/templates/horizon/common/_workflow.html
deleted file mode 100644
index 4730af1b..00000000
--- a/horizon/templates/horizon/common/_workflow.html
+++ /dev/null
@@ -1,43 +0,0 @@
-{% load i18n %}
-{% with workflow.get_entry_point as entry_point %}
-<div class="workflow {% if modal %}modal hide{% else %}static_page{% endif %}">
- <form {{ workflow.attr_string|safe }} action="{{ workflow.get_absolute_url }}" {% if add_to_field %}data-add-to-field="{{ add_to_field }}"{% endif %} method="POST"{% if workflow.multipart %} enctype="multipart/form-data"{% endif %}>{% csrf_token %}
- {% if REDIRECT_URL %}<input type="hidden" name="{{ workflow.redirect_param_name }}" value="{{ REDIRECT_URL }}"/>{% endif %}
- <div class="modal-header">
- {% block modal-header %}
- {% if modal %}<a href="#" class="close" data-dismiss="modal">&times;</a>{% endif %}
- <h3>{{ workflow.name }}</h3>
- {% endblock %}
- </div>
- <div class="modal-body clearfix">
- {% block modal-body %}
- <ul class="nav nav-tabs">
- {% for step in workflow.steps %}
- <li class="{% if entry_point == step.slug %}active{% endif %}{% if step.has_errors %} error{% endif %}">
- <a href="#{{ step.get_id }}" data-toggle="tab" data-target="#{{ step.get_id }}">{{ step }}</a>
- </li>
- {% endfor %}
- </ul>
- <div class="tab-content">
- {% for step in workflow.steps %}
- <fieldset id="{{ step.get_id }}" class="js-tab-pane{% if entry_point == step.slug %} active{% endif %}">
- {{ step.render }}
- </fieldset>
- {% if not forloop.last %}
- <noscript><hr /></noscript>
- {% endif %}
- {% endfor %}
- </div>
- {% endblock %}
- </div>
- <div class="modal-footer">
- {% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{{ workflow.finalize_button_name }}" />
- {% if modal %}<a class="btn secondary cancel close">{% trans "Cancel" %}</a>{% endif %}
- {% endblock %}
- </div>
- </form>
-</div>
-{% endwith %}
-{% block modal-js %}
-{% endblock %}
diff --git a/horizon/templates/horizon/common/_workflow_base.html b/horizon/templates/horizon/common/_workflow_base.html
deleted file mode 100644
index c3401cc6..00000000
--- a/horizon/templates/horizon/common/_workflow_base.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans workflow.name %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=workflow.name %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'horizon/common/_workflow.html' %}
-{% endblock %}
diff --git a/horizon/templates/horizon/common/_workflow_step.html b/horizon/templates/horizon/common/_workflow_step.html
deleted file mode 100644
index 17b6deff..00000000
--- a/horizon/templates/horizon/common/_workflow_step.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<noscript><h3>{{ step }}</h3></noscript>
-<table class="table-fixed">
- <tbody>
- <tr>
- <td class="actions">
- {% include "horizon/common/_form_fields.html" %}
- </td>
- <td class="help_text">
- {{ step.get_help_text }}
- </td>
- </tr>
- </tbody>
-</table>
diff --git a/horizon/templates/horizon/common/_workflow_step_update_members.html b/horizon/templates/horizon/common/_workflow_step_update_members.html
deleted file mode 100644
index 31c8a001..00000000
--- a/horizon/templates/horizon/common/_workflow_step_update_members.html
+++ /dev/null
@@ -1,50 +0,0 @@
-{% load i18n %}
-
-<noscript><h3>{{ step }}</h3></noscript>
-
-<div class="project_membership" data-show-roles="{{ step.show_roles|yesno }}">
- <div class="header">
- <div class="help_text">{{ step.help_text }}</div>
- <div class="left">
- <div class="fake_table fake_table_header">
- <span class="users_title">{{ step.available_list_title }}</span>
- <input type="text" name="available_users_filter" id="available_users" class="filter" placeholder="Filter">
- </div>
- </div>
- <div class="right">
- <div class="fake_table fake_table_header">
- <span class="users_title">{{ step.members_list_title }}</span>
- <input type="text" name="project_members_filter" id="project_members" class="filter" placeholder="Filter">
- </div>
- </div>
- </div>
-
- <div class="left filterable">
- <div class="fake_table" id="available_users">
- <ul class="available_users"></ul>
- <ul class="no_results" id="no_available_users"><li>{{ step.no_available_text }}</li></ul>
- </div>
- </div>
-
- <div class="right filterable">
- <div class="fake_table" id="project_members">
- <ul class="project_members"></ul>
- <ul class="no_results" id="no_project_members"><li>{{ step.no_members_text }}</li></ul>
- </div>
- </div>
-</div>
-
-<div class="hide">
- {% include "horizon/common/_form_fields.html" %}
-</div>
-
-
-<script>
- if (typeof $ !== 'undefined') {
- horizon.projects.workflow_init($(".workflow"));
- } else {
- addHorizonLoadEvent(function() {
- horizon.projects.workflow_init($(".workflow"));
- });
- }
-</script>
diff --git a/horizon/templates/horizon/qunit.html b/horizon/templates/horizon/qunit.html
deleted file mode 100644
index 5f0028d7..00000000
--- a/horizon/templates/horizon/qunit.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8" />
- <title>Horizon QUnit Test Suite</title>
- <link rel="stylesheet" href="{{ STATIC_URL }}horizon/lib/qunit/qunit.css" type="text/css" media="screen">
- <script type="text/javascript" src="{{ STATIC_URL }}horizon/lib/jquery/jquery.min.js"></script>
- <script type="text/javascript" src="{{ STATIC_URL }}horizon/lib/qunit/qunit.js"></script>
- {% include "horizon/_conf.html" %}
-
- {% comment %}Load test modules here.{% endcomment %}
- <script type="text/javascript" src="{{ STATIC_URL }}horizon/tests/messages.js"></script>
- <script type="text/javascript" src="{{ STATIC_URL }}horizon/tests/modals.js"></script>
- <script type="text/javascript" src="{{ STATIC_URL }}horizon/tests/templates.js"></script>
- <script type="text/javascript" src="{{ STATIC_URL }}horizon/tests/tables.js"></script>
- {% comment %}End test modules.{% endcomment %}
-
- {% include "horizon/_scripts.html" %}
- </head>
- <body>
- <h1 id="qunit-header">Horizon JavaScript Tests</h1>
- <h2 id="qunit-banner"></h2>
- <div id="qunit-testrunner-toolbar"></div>
- <h2 id="qunit-userAgent"></h2>
- <ol id="qunit-tests"></ol>
- <div id="qunit-fixture">
- <!-- Test markup; will be hidden. -->
-
- <div id="main_content">
- <div class="messages"></div>
- <div id="modal_wrapper"></div>
- </div>
-
- <table id="table1" class="datatable">
- <tbody>
- <tr><td>cat1</td></tr>
- <tr><td>dog1</td></tr>
- <tr><td>cat2</td></tr>
- <tr><td>dog2</td></tr>
- </tbody>
- <tfoot>
- <tr>
- <td colspan="1">
- <span class="table_count">Displaying 4 items</span>
- </td>
- </tr>
- </tfoot>
- </table>
-
- <table id="table2" class="datatable">
- <thead><tr><th><div class="table_filter" data-toggle="buttons-radio">
- <button name="cats" type="submit" value="cats" id="button_cats">Cats</button>
- <button name="dogs" type="submit" value="dogs" id="button_dogs">Dogs</button>
- <button name="big" type="submit" value="big" id="button_big">Big Animals</button>
- </div></th></tr></thead>
- <tbody>
- <tr class="category-cat"><td>cat1</td></tr>
- <tr class="category-big category-dog"><td>dog1</td></tr>
- <tr class="category-big category-cat"><td>cat2</td></tr>
- <tr class="category-dog"><td>dog2</td></tr>
- </tbody>
- <tfoot>
- <tr>
- <td colspan="1">
- <span class="table_count">Displaying 4 items</span>
- </td>
- </tr>
- </tfoot>
- </table>
-
- </div>
- </body>
-</html>
diff --git a/horizon/templates/splash.html b/horizon/templates/splash.html
deleted file mode 100644
index 4a5cfe12..00000000
--- a/horizon/templates/splash.html
+++ /dev/null
@@ -1,17 +0,0 @@
-{% load i18n branding %}
-
-<!DOCTYPE html>
-<html lang="en" xml:lang="en">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <title>{% trans "Login" %} - {% site_branding %}</title>
- {% include "_stylesheets.html" %}
- </head>
- <body id="splash">
- <div class="container">
- <div class="row large-rounded">
- {% include 'auth/_login.html' %}
- </div>
- </div>
- </body>
-</html>
diff --git a/horizon/templatetags/__init__.py b/horizon/templatetags/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/templatetags/__init__.py
+++ /dev/null
diff --git a/horizon/templatetags/branding.py b/horizon/templatetags/branding.py
deleted file mode 100644
index 195c4cdf..00000000
--- a/horizon/templatetags/branding.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Template tags for customizing Horizon.
-"""
-
-from django.conf import settings
-from django import template
-from django.utils.translation import ugettext_lazy as _
-
-
-register = template.Library()
-
-
-class SiteBrandingNode(template.Node):
- def render(self, context):
- return getattr(settings, "SITE_BRANDING", _("Horizon"))
-
-
-@register.tag
-def site_branding(parser, token):
- return SiteBrandingNode()
-
-
-@register.tag
-def site_title(parser, token):
- return settings.SITE_BRANDING
-
-
-# TODO(jeffjapan): This is just an assignment tag version of the above, replace
-# when the dashboard is upgraded to a django version that
-# supports the @assignment_tag decorator syntax instead.
-class SaveBrandingNode(template.Node):
- def __init__(self, var_name):
- self.var_name = var_name
-
- def render(self, context):
- context[self.var_name] = settings.SITE_BRANDING
- return ""
-
-
-@register.tag
-def save_site_branding(parser, token):
- tagname = token.contents.split()
- return SaveBrandingNode(tagname[-1])
diff --git a/horizon/templatetags/horizon.py b/horizon/templatetags/horizon.py
deleted file mode 100644
index 4de7ab33..00000000
--- a/horizon/templatetags/horizon.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from __future__ import absolute_import
-
-from django import template
-from django.utils.datastructures import SortedDict
-from django.utils.encoding import force_unicode
-from django.utils.translation import ugettext_lazy as _
-
-from horizon.base import Horizon
-from horizon import conf
-
-
-register = template.Library()
-
-
-@register.filter
-def has_permissions(user, component):
- """
- Checks if the given user meets the permissions requirements for
- the component.
- """
- return user.has_perms(getattr(component, 'permissions', set()))
-
-
-@register.filter
-def has_permissions_on_list(components, user):
- return [component for component
- in components if has_permissions(user, component)]
-
-
-@register.inclusion_tag('horizon/_nav_list.html', takes_context=True)
-def horizon_main_nav(context):
- """ Generates top-level dashboard navigation entries. """
- if 'request' not in context:
- return {}
- current_dashboard = context['request'].horizon.get('dashboard', None)
- dashboards = []
- for dash in Horizon.get_dashboards():
- if callable(dash.nav) and dash.nav(context):
- dashboards.append(dash)
- elif dash.nav:
- dashboards.append(dash)
- return {'components': dashboards,
- 'user': context['request'].user,
- 'current': current_dashboard,
- 'request': context['request']}
-
-
-@register.inclusion_tag('horizon/_subnav_list.html', takes_context=True)
-def horizon_dashboard_nav(context):
- """ Generates sub-navigation entries for the current dashboard. """
- if 'request' not in context:
- return {}
- dashboard = context['request'].horizon['dashboard']
- panel_groups = dashboard.get_panel_groups()
- non_empty_groups = []
-
- for group in panel_groups.values():
- allowed_panels = []
- for panel in group:
- if callable(panel.nav) and panel.nav(context):
- allowed_panels.append(panel)
- elif not callable(panel.nav) and panel.nav:
- allowed_panels.append(panel)
- if allowed_panels:
- non_empty_groups.append((group.name, allowed_panels))
-
- return {'components': SortedDict(non_empty_groups),
- 'user': context['request'].user,
- 'current': context['request'].horizon['panel'].slug,
- 'request': context['request']}
-
-
-@register.filter
-def quota(val, units=None):
- if val == float("inf"):
- return _("No Limit")
- elif units is not None:
- return "%s %s %s" % (val, units, force_unicode(_("Available")))
- else:
- return "%s %s" % (val, force_unicode(_("Available")))
-
-
-class JSTemplateNode(template.Node):
- """ Helper node for the ``jstemplate`` template tag. """
- def __init__(self, nodelist):
- self.nodelist = nodelist
-
- def render(self, context, ):
- output = self.nodelist.render(context)
- output = output.replace('[[[', '{{{').replace(']]]', '}}}')
- output = output.replace('[[', '{{').replace(']]', '}}')
- output = output.replace('[%', '{%').replace('%]', '%}')
- return output
-
-
-@register.tag
-def jstemplate(parser, token):
- """
- Replaces ``[[[`` and ``]]]`` with ``{{{`` and ``}}}``,
- ``[[`` and ``]]`` with ``{{`` and ``}}`` and
- ``[%`` and ``%]`` with ``{%`` and ``%}`` to avoid conflicts
- with Django's template engine when using any of the Mustache-based
- templating libraries.
- """
- nodelist = parser.parse(('endjstemplate',))
- parser.delete_first_token()
- return JSTemplateNode(nodelist)
-
-
-@register.assignment_tag
-def load_config():
- return conf.HORIZON_CONFIG
diff --git a/horizon/templatetags/parse_date.py b/horizon/templatetags/parse_date.py
deleted file mode 100644
index f4309a75..00000000
--- a/horizon/templatetags/parse_date.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Template tags for parsing date strings.
-"""
-
-from datetime import datetime
-from django import template
-from django.utils import timezone
-
-
-register = template.Library()
-
-
-class ParseDateNode(template.Node):
- def render(self, datestring):
- """
- Parses a date-like input string into a timezone aware Python datetime.
- """
- formats = ["%Y-%m-%dT%H:%M:%S.%f", "%Y-%m-%d %H:%M:%S.%f",
- "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"]
- if datestring:
- for format in formats:
- try:
- parsed = datetime.strptime(datestring, format)
- if not timezone.is_aware(parsed):
- parsed = timezone.make_aware(parsed, timezone.utc)
- return parsed
- except:
- pass
- return None
-
-
-@register.filter(name='parse_date')
-def parse_date(value):
- return ParseDateNode().render(value)
diff --git a/horizon/templatetags/sizeformat.py b/horizon/templatetags/sizeformat.py
deleted file mode 100644
index ee2ba41a..00000000
--- a/horizon/templatetags/sizeformat.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Template tags for displaying sizes
-"""
-
-from django import template
-from django.utils import formats
-from django.utils import translation
-
-
-register = template.Library()
-
-
-def int_format(value):
- return int(value)
-
-
-def float_format(value):
- return formats.number_format(round(value, 1), 0)
-
-
-def filesizeformat(bytes, filesize_number_format):
- try:
- bytes = float(bytes)
- except (TypeError, ValueError, UnicodeDecodeError):
- return translation.ungettext_lazy("%(size)d byte",
- "%(size)d bytes", 0) % {'size': 0}
-
- if bytes < 1024:
- return translation.ungettext_lazy("%(size)d",
- "%(size)d", bytes) % {'size': bytes}
- if bytes < 1024 * 1024:
- return translation.ugettext_lazy("%s KB") % \
- filesize_number_format(bytes / 1024)
- if bytes < 1024 * 1024 * 1024:
- return translation.ugettext_lazy("%s MB") % \
- filesize_number_format(bytes / (1024 * 1024))
- if bytes < 1024 * 1024 * 1024 * 1024:
- return translation.ugettext_lazy("%s GB") % \
- filesize_number_format(bytes / (1024 * 1024 * 1024))
- if bytes < 1024 * 1024 * 1024 * 1024 * 1024:
- return translation.ugettext_lazy("%s TB") % \
- filesize_number_format(bytes / (1024 * 1024 * 1024 * 1024))
- return translation.ugettext_lazy("%s PB") % \
- filesize_number_format(bytes / (1024 * 1024 * 1024 * 1024 * 1024))
-
-
-@register.filter(name='mbformat')
-def mbformat(mb):
- if not mb:
- return 0
- return filesizeformat(mb * 1024 * 1024, int_format).replace(' ', '')
-
-
-@register.filter(name='diskgbformat')
-def diskgbformat(gb):
- return filesizeformat(gb * 1024 * 1024 * 1024,
- float_format).replace(' ', '')
diff --git a/horizon/templatetags/truncate_filter.py b/horizon/templatetags/truncate_filter.py
deleted file mode 100644
index aca8468a..00000000
--- a/horizon/templatetags/truncate_filter.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Template tags for truncating strings.
-"""
-
-from django import template
-
-register = template.Library()
-
-
-@register.filter("truncate")
-def truncate(value, size):
- if len(value) > size and size > 3:
- return value[0:(size - 3)] + '...'
- else:
- return value[0:size]
diff --git a/horizon/test/__init__.py b/horizon/test/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/__init__.py
+++ /dev/null
diff --git a/horizon/test/customization/__init__.py b/horizon/test/customization/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/customization/__init__.py
+++ /dev/null
diff --git a/horizon/test/customization/cust_test1.py b/horizon/test/customization/cust_test1.py
deleted file mode 100644
index 965f1faf..00000000
--- a/horizon/test/customization/cust_test1.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-# Rename "cats" to "wildcats"
-cats = horizon.get_dashboard("cats")
-cats.name = _("WildCats")
-
-# Disable tigers panel
-tigers = cats.get_panel("tigers")
-cats.unregister(tigers.__class__)
-
-# Remove dogs dashboard
-dogs = horizon.get_dashboard("dogs")
-horizon.unregister(dogs.__class__)
diff --git a/horizon/test/customization/cust_test2.py b/horizon/test/customization/cust_test2.py
deleted file mode 100644
index 2bdba0d2..00000000
--- a/horizon/test/customization/cust_test2.py
+++ /dev/null
@@ -1,9 +0,0 @@
-import horizon
-
-dogs = horizon.get_dashboard("dogs")
-
-puppies = dogs.get_panel("puppies")
-
-permissions = list(getattr(puppies, 'permissions', []))
-permissions.append('horizon.test')
-puppies.permissions = tuple(permissions)
diff --git a/horizon/test/helpers.py b/horizon/test/helpers.py
deleted file mode 100644
index 9253f20d..00000000
--- a/horizon/test/helpers.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-import os
-import socket
-
-from django.contrib.auth.middleware import AuthenticationMiddleware
-from django.contrib.auth.models import Permission
-from django.contrib.auth.models import User
-from django.contrib.contenttypes.models import ContentType
-from django.contrib.messages.storage import default_storage
-from django.core.handlers import wsgi
-from django import http
-from django import test as django_test
-from django.test.client import RequestFactory
-from django.utils import unittest
-
-LOG = logging.getLogger(__name__)
-
-
-try:
- from selenium.webdriver.firefox.webdriver import WebDriver
- from selenium.webdriver.support import ui as selenium_ui
-except ImportError as e:
- # NOTE(saschpe): Several distribution can't ship selenium due to it's
- # non-free license. So they have to patch it out of test-requirements.txt
- # Avoid import failure and force not running selenium tests.
- LOG.warning("{0}, force WITH_SELENIUM=False".format(str(e)))
- os.environ['WITH_SELENIUM'] = ''
-
-
-import mox
-
-from horizon import middleware
-
-
-# Makes output of failing mox tests much easier to read.
-wsgi.WSGIRequest.__repr__ = lambda self: "<class 'django.http.HttpRequest'>"
-
-
-class RequestFactoryWithMessages(RequestFactory):
- def get(self, *args, **kwargs):
- req = super(RequestFactoryWithMessages, self).get(*args, **kwargs)
- req.user = User()
- req.session = []
- req._messages = default_storage(req)
- return req
-
- def post(self, *args, **kwargs):
- req = super(RequestFactoryWithMessages, self).post(*args, **kwargs)
- req.user = User()
- req.session = []
- req._messages = default_storage(req)
- return req
-
-
-@unittest.skipIf(os.environ.get('SKIP_UNITTESTS', False),
- "The SKIP_UNITTESTS env variable is set.")
-class TestCase(django_test.TestCase):
- """
- Specialized base test case class for Horizon which gives access to
- numerous additional features:
-
- * The ``mox`` mocking framework via ``self.mox``.
- * A ``RequestFactory`` class which supports Django's ``contrib.messages``
- framework via ``self.factory``.
- * A ready-to-go request object via ``self.request``.
- """
- def setUp(self):
- self.mox = mox.Mox()
- self.factory = RequestFactoryWithMessages()
- self.user = User.objects.create_user(username='test', password='test')
- self.assertTrue(self.client.login(username="test", password="test"))
-
- self.request = http.HttpRequest()
- self.request.session = self.client._session()
- middleware.HorizonMiddleware().process_request(self.request)
- AuthenticationMiddleware().process_request(self.request)
- os.environ["HORIZON_TEST_RUN"] = "True"
-
- def tearDown(self):
- self.mox.UnsetStubs()
- self.mox.VerifyAll()
- del os.environ["HORIZON_TEST_RUN"]
-
- def set_permissions(self, permissions=None):
- perm_ids = Permission.objects.values_list('id', flat=True)
- self.user.user_permissions.remove(*perm_ids)
- for name in permissions:
- ct, create = ContentType.objects.get_or_create(model=name,
- app_label='horizon')
- perm, create = Permission.objects.get_or_create(codename=name,
- content_type=ct,
- name=name)
- self.user.user_permissions.add(perm)
- if hasattr(self.user, "_perm_cache"):
- del self.user._perm_cache
-
- def assertNoMessages(self, response=None):
- """
- Asserts that no messages have been attached by the ``contrib.messages``
- framework.
- """
- self.assertMessageCount(response, success=0, warn=0, info=0, error=0)
-
- def assertMessageCount(self, response=None, **kwargs):
- """
- Asserts that the specified number of messages have been attached
- for various message types. Usage would look like
- ``self.assertMessageCount(success=1)``.
- """
- temp_req = self.client.request(**{'wsgi.input': None})
- temp_req.COOKIES = self.client.cookies
- storage = default_storage(temp_req)
- messages = []
-
- if response is None:
- # To gain early access to the messages we have to decode the
- # cookie on the test client.
- if 'messages' in self.client.cookies:
- message_cookie = self.client.cookies['messages'].value
- messages = storage._decode(message_cookie)
- # Check for messages in the context
- elif hasattr(response, "context") and "messages" in response.context:
- messages = response.context["messages"]
- # Check for messages attached to the request on a TemplateResponse
- elif hasattr(response, "_request") and hasattr(response._request,
- "_messages"):
- messages = response._request._messages._queued_messages
-
- # If we don't have messages and we don't expect messages, we're done.
- if not any(kwargs.values()) and not messages:
- return
-
- # If we expected messages and have none, that's a problem.
- if any(kwargs.values()) and not messages:
- error_msg = "Messages were expected, but none were set."
- assert 0 == sum(kwargs.values()), error_msg
-
- # Otherwise, make sure we got the expected messages.
- for msg_type, count in kwargs.items():
- msgs = [m.message for m in messages if msg_type in m.tags]
- assert len(msgs) == count, \
- "%s messages not as expected: %s" % (msg_type.title(),
- ", ".join(msgs))
-
-
-@unittest.skipUnless(os.environ.get('WITH_SELENIUM', False),
- "The WITH_SELENIUM env variable is not set.")
-class SeleniumTestCase(django_test.LiveServerTestCase):
- @classmethod
- def setUpClass(cls):
- if os.environ.get('WITH_SELENIUM', False):
- cls.selenium = WebDriver()
- super(SeleniumTestCase, cls).setUpClass()
-
- @classmethod
- def tearDownClass(cls):
- if os.environ.get('WITH_SELENIUM', False):
- cls.selenium.quit()
- super(SeleniumTestCase, cls).tearDownClass()
-
- def setUp(self):
- socket.setdefaulttimeout(10)
- self.ui = selenium_ui
- super(SeleniumTestCase, self).setUp()
diff --git a/horizon/test/settings.py b/horizon/test/settings.py
deleted file mode 100644
index 98c52721..00000000
--- a/horizon/test/settings.py
+++ /dev/null
@@ -1,180 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import os
-import socket
-
-from django.utils.translation import ugettext_lazy as _
-
-
-socket.setdefaulttimeout(1)
-
-LOGIN_URL = '/auth/login/'
-LOGOUT_URL = '/auth/logout/'
-LOGIN_REDIRECT_URL = '/'
-
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-DEBUG = False
-TEMPLATE_DEBUG = DEBUG
-TESTSERVER = 'http://testserver'
-
-SECRET_KEY = 'elj1IWiLoWHgcyYxFVLj7cM5rGOOxWl0'
-
-USE_I18N = True
-USE_L10N = True
-USE_TZ = True
-
-DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3'}}
-
-DEFAULT_EXCEPTION_REPORTER_FILTER = 'horizon.exceptions.HorizonReporterFilter'
-
-INSTALLED_APPS = (
- 'django.contrib.sessions',
- 'django.contrib.staticfiles',
- 'django.contrib.messages',
- 'django.contrib.humanize',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django_nose',
- 'compressor',
- 'horizon',
- 'horizon.test',
- 'horizon.test.test_dashboards.cats',
- 'horizon.test.test_dashboards.dogs'
-)
-
-MIDDLEWARE_CLASSES = (
- 'django.middleware.common.CommonMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',
- 'django.middleware.doc.XViewMiddleware',
- 'django.middleware.locale.LocaleMiddleware',
- 'horizon.middleware.HorizonMiddleware')
-
-TEMPLATE_CONTEXT_PROCESSORS = (
- 'django.core.context_processors.debug',
- 'django.core.context_processors.i18n',
- 'django.core.context_processors.request',
- 'django.core.context_processors.media',
- 'django.core.context_processors.static',
- 'django.contrib.messages.context_processors.messages',
- 'horizon.context_processors.horizon')
-
-TEMPLATE_LOADERS = (
- 'django.template.loaders.filesystem.Loader',
- 'django.template.loaders.app_directories.Loader',
- 'horizon.loaders.TemplateLoader'
-)
-
-STATIC_URL = '/static/'
-
-MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
-
-ROOT_URLCONF = 'horizon.test.urls'
-TEMPLATE_DIRS = (os.path.join(ROOT_PATH, 'tests', 'templates'))
-SITE_ID = 1
-SITE_BRANDING = 'Horizon'
-
-TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
-NOSE_ARGS = ['--nocapture',
- '--nologcapture',
- '--exclude-dir=horizon/conf/',
- '--exclude-dir=horizon/test/customization',
- '--cover-package=horizon',
- '--cover-inclusive',
- '--all-modules']
-
-EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
-SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
-SESSION_COOKIE_HTTPONLY = True
-SESSION_EXPIRE_AT_BROWSER_CLOSE = True
-SESSION_COOKIE_SECURE = False
-
-HORIZON_CONFIG = {
- 'dashboards': ('cats', 'dogs'),
- 'default_dashboard': 'cats',
- "password_validator": {
- "regex": '^.{8,18}$',
- "help_text": _("Password must be between 8 and 18 characters.")
- },
- 'user_home': None,
- 'help_url': "http://example.com"
-}
-
-COMPRESS_ENABLED = False
-COMPRESS_OFFLINE = False
-COMPRESS_ROOT = "/tmp/"
-
-STATICFILES_FINDERS = (
- 'django.contrib.staticfiles.finders.FileSystemFinder',
- 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
- 'compressor.finders.CompressorFinder',
-)
-
-LOGGING = {
- 'version': 1,
- 'disable_existing_loggers': False,
- 'handlers': {
- 'null': {
- 'level': 'DEBUG',
- 'class': 'django.utils.log.NullHandler',
- },
- 'test': {
- 'level': 'ERROR',
- 'class': 'logging.StreamHandler',
- }
- },
- 'loggers': {
- 'django.db.backends': {
- 'handlers': ['null'],
- 'propagate': False,
- },
- 'horizon': {
- 'handlers': ['test'],
- 'propagate': False,
- },
- 'novaclient': {
- 'handlers': ['test'],
- 'propagate': False,
- },
- 'keystoneclient': {
- 'handlers': ['test'],
- 'propagate': False,
- },
- 'glanceclient': {
- 'handlers': ['test'],
- 'propagate': False,
- },
- 'neutronclient': {
- 'handlers': ['test'],
- 'propagate': False,
- },
- 'nose.plugins.manager': {
- 'handlers': ['null'],
- 'propagate': False,
- },
- 'selenium': {
- 'handlers': ['null'],
- 'propagate': False,
- }
- }
-}
diff --git a/horizon/test/templates/404.html b/horizon/test/templates/404.html
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/templates/404.html
+++ /dev/null
diff --git a/horizon/test/templates/_tab.html b/horizon/test/templates/_tab.html
deleted file mode 100644
index e336d411..00000000
--- a/horizon/test/templates/_tab.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ tab.name }}
diff --git a/horizon/test/templates/base-sidebar.html b/horizon/test/templates/base-sidebar.html
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/templates/base-sidebar.html
+++ /dev/null
diff --git a/horizon/test/templates/registration/login.html b/horizon/test/templates/registration/login.html
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/templates/registration/login.html
+++ /dev/null
diff --git a/horizon/test/templates/tab_group.html b/horizon/test/templates/tab_group.html
deleted file mode 100644
index 94b2e517..00000000
--- a/horizon/test/templates/tab_group.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ tab_group.render }}
diff --git a/horizon/test/templates/workflow.html b/horizon/test/templates/workflow.html
deleted file mode 100644
index 02ec6658..00000000
--- a/horizon/test/templates/workflow.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ workflow.render }}
diff --git a/horizon/test/test_dashboards/__init__.py b/horizon/test/test_dashboards/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/test_dashboards/__init__.py
+++ /dev/null
diff --git a/horizon/test/test_dashboards/cats/__init__.py b/horizon/test/test_dashboards/cats/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/test_dashboards/cats/__init__.py
+++ /dev/null
diff --git a/horizon/test/test_dashboards/cats/dashboard.py b/horizon/test/test_dashboards/cats/dashboard.py
deleted file mode 100644
index 25c2bd4b..00000000
--- a/horizon/test/test_dashboards/cats/dashboard.py
+++ /dev/null
@@ -1,25 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-
-class CuteGroup(horizon.PanelGroup):
- slug = "cute"
- name = _("Cute Cats")
- panels = ('kittens',)
-
-
-class FierceGroup(horizon.PanelGroup):
- slug = "fierce"
- name = _("Fierce Cats")
- panels = ("tigers",)
-
-
-class Cats(horizon.Dashboard):
- name = _("Cats")
- slug = "cats"
- panels = (CuteGroup, FierceGroup)
- default_panel = 'kittens'
-
-
-horizon.register(Cats)
diff --git a/horizon/test/test_dashboards/cats/kittens/__init__.py b/horizon/test/test_dashboards/cats/kittens/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/test_dashboards/cats/kittens/__init__.py
+++ /dev/null
diff --git a/horizon/test/test_dashboards/cats/kittens/models.py b/horizon/test/test_dashboards/cats/kittens/models.py
deleted file mode 100644
index 1b3d5f9e..00000000
--- a/horizon/test/test_dashboards/cats/kittens/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/horizon/test/test_dashboards/cats/kittens/panel.py b/horizon/test/test_dashboards/cats/kittens/panel.py
deleted file mode 100644
index a56e9c3f..00000000
--- a/horizon/test/test_dashboards/cats/kittens/panel.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from horizon.test.test_dashboards.cats import dashboard
-
-
-class Kittens(horizon.Panel):
- name = _("Kittens")
- slug = "kittens"
- permissions = ("horizon.test",)
-
-
-dashboard.Cats.register(Kittens)
diff --git a/horizon/test/test_dashboards/cats/kittens/templates/kittens/index.html b/horizon/test/test_dashboards/cats/kittens/templates/kittens/index.html
deleted file mode 100644
index 2483c434..00000000
--- a/horizon/test/test_dashboards/cats/kittens/templates/kittens/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'cats/base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Kittens" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Kittens") %}
-{% endblock page_header %}
-
-{% block cats_main %}
-{% endblock %}
-
-
diff --git a/horizon/test/test_dashboards/cats/kittens/urls.py b/horizon/test/test_dashboards/cats/kittens/urls.py
deleted file mode 100644
index f6605971..00000000
--- a/horizon/test/test_dashboards/cats/kittens/urls.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from horizon.test.test_dashboards.cats.kittens.views import IndexView
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
-)
diff --git a/horizon/test/test_dashboards/cats/kittens/views.py b/horizon/test/test_dashboards/cats/kittens/views.py
deleted file mode 100644
index 9b17cae5..00000000
--- a/horizon/test/test_dashboards/cats/kittens/views.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from horizon import views
-
-
-class IndexView(views.APIView):
- # A very simple class-based view...
- template_name = 'cats/kittens/index.html'
-
- def get_data(self, request, context, *args, **kwargs):
- # Add data to the context here...
- return context
diff --git a/horizon/test/test_dashboards/cats/models.py b/horizon/test/test_dashboards/cats/models.py
deleted file mode 100644
index 1b3d5f9e..00000000
--- a/horizon/test/test_dashboards/cats/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/horizon/test/test_dashboards/cats/static/cats/css/cats.css b/horizon/test/test_dashboards/cats/static/cats/css/cats.css
deleted file mode 100644
index 52a96f58..00000000
--- a/horizon/test/test_dashboards/cats/static/cats/css/cats.css
+++ /dev/null
@@ -1 +0,0 @@
-/* Additional CSS for cats. */
diff --git a/horizon/test/test_dashboards/cats/static/cats/js/cats.js b/horizon/test/test_dashboards/cats/static/cats/js/cats.js
deleted file mode 100644
index 4e3a6d42..00000000
--- a/horizon/test/test_dashboards/cats/static/cats/js/cats.js
+++ /dev/null
@@ -1 +0,0 @@
-/* Additional JavaScript for cats. */
diff --git a/horizon/test/test_dashboards/cats/templates/cats/base.html b/horizon/test/test_dashboards/cats/templates/cats/base.html
deleted file mode 100644
index f9d1b958..00000000
--- a/horizon/test/test_dashboards/cats/templates/cats/base.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-
-{% block sidebar %}
- {% include 'horizon/common/_sidebar.html' %}
-{% endblock %}
-
-{% block main %}
- {% include "horizon/_messages.html" %}
- {% block cats_main %}{% endblock %}
-{% endblock %}
-
diff --git a/horizon/test/test_dashboards/cats/tigers/__init__.py b/horizon/test/test_dashboards/cats/tigers/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/test_dashboards/cats/tigers/__init__.py
+++ /dev/null
diff --git a/horizon/test/test_dashboards/cats/tigers/models.py b/horizon/test/test_dashboards/cats/tigers/models.py
deleted file mode 100644
index 1b3d5f9e..00000000
--- a/horizon/test/test_dashboards/cats/tigers/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/horizon/test/test_dashboards/cats/tigers/panel.py b/horizon/test/test_dashboards/cats/tigers/panel.py
deleted file mode 100644
index 6439ef51..00000000
--- a/horizon/test/test_dashboards/cats/tigers/panel.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from horizon.test.test_dashboards.cats import dashboard
-
-
-class Tigers(horizon.Panel):
- name = _("Tigers")
- slug = "tigers"
- permissions = ("horizon.test",)
-
-
-dashboard.Cats.register(Tigers)
diff --git a/horizon/test/test_dashboards/cats/tigers/templates/tigers/index.html b/horizon/test/test_dashboards/cats/tigers/templates/tigers/index.html
deleted file mode 100644
index 742b68e4..00000000
--- a/horizon/test/test_dashboards/cats/tigers/templates/tigers/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'cats/base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Tigers" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Tigers") %}
-{% endblock page_header %}
-
-{% block cats_main %}
-{% endblock %}
-
-
diff --git a/horizon/test/test_dashboards/cats/tigers/urls.py b/horizon/test/test_dashboards/cats/tigers/urls.py
deleted file mode 100644
index 65352324..00000000
--- a/horizon/test/test_dashboards/cats/tigers/urls.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from horizon.test.test_dashboards.cats.tigers.views import IndexView
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
-)
diff --git a/horizon/test/test_dashboards/cats/tigers/views.py b/horizon/test/test_dashboards/cats/tigers/views.py
deleted file mode 100644
index 483f789b..00000000
--- a/horizon/test/test_dashboards/cats/tigers/views.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from horizon import views
-
-
-class IndexView(views.APIView):
- # A very simple class-based view...
- template_name = 'cats/tigers/index.html'
-
- def get_data(self, request, context, *args, **kwargs):
- # Add data to the context here...
- return context
diff --git a/horizon/test/test_dashboards/dogs/__init__.py b/horizon/test/test_dashboards/dogs/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/test_dashboards/dogs/__init__.py
+++ /dev/null
diff --git a/horizon/test/test_dashboards/dogs/dashboard.py b/horizon/test/test_dashboards/dogs/dashboard.py
deleted file mode 100644
index 0596eb4e..00000000
--- a/horizon/test/test_dashboards/dogs/dashboard.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-
-class Dogs(horizon.Dashboard):
- name = _("Dogs")
- slug = "dogs"
- panels = ('puppies',)
- default_panel = 'puppies'
-
-
-horizon.register(Dogs)
diff --git a/horizon/test/test_dashboards/dogs/models.py b/horizon/test/test_dashboards/dogs/models.py
deleted file mode 100644
index 1b3d5f9e..00000000
--- a/horizon/test/test_dashboards/dogs/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/horizon/test/test_dashboards/dogs/puppies/__init__.py b/horizon/test/test_dashboards/dogs/puppies/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/test_dashboards/dogs/puppies/__init__.py
+++ /dev/null
diff --git a/horizon/test/test_dashboards/dogs/puppies/models.py b/horizon/test/test_dashboards/dogs/puppies/models.py
deleted file mode 100644
index 1b3d5f9e..00000000
--- a/horizon/test/test_dashboards/dogs/puppies/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/horizon/test/test_dashboards/dogs/puppies/panel.py b/horizon/test/test_dashboards/dogs/puppies/panel.py
deleted file mode 100644
index a660436d..00000000
--- a/horizon/test/test_dashboards/dogs/puppies/panel.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from horizon.test.test_dashboards.dogs import dashboard
-
-
-class Puppies(horizon.Panel):
- name = _("Puppies")
- slug = "puppies"
-
-
-dashboard.Dogs.register(Puppies)
diff --git a/horizon/test/test_dashboards/dogs/puppies/templates/puppies/index.html b/horizon/test/test_dashboards/dogs/puppies/templates/puppies/index.html
deleted file mode 100644
index 40371650..00000000
--- a/horizon/test/test_dashboards/dogs/puppies/templates/puppies/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'dogs/base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Puppies" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Puppies") %}
-{% endblock page_header %}
-
-{% block dogs_main %}
-{% endblock %}
-
-
diff --git a/horizon/test/test_dashboards/dogs/puppies/urls.py b/horizon/test/test_dashboards/dogs/puppies/urls.py
deleted file mode 100644
index 35650185..00000000
--- a/horizon/test/test_dashboards/dogs/puppies/urls.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from horizon.test.test_dashboards.dogs.puppies.views import IndexView
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
-)
diff --git a/horizon/test/test_dashboards/dogs/puppies/views.py b/horizon/test/test_dashboards/dogs/puppies/views.py
deleted file mode 100644
index 3f1df5e2..00000000
--- a/horizon/test/test_dashboards/dogs/puppies/views.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from horizon import views
-
-
-class IndexView(views.APIView):
- # A very simple class-based view...
- template_name = 'dogs/puppies/index.html'
-
- def get_data(self, request, context, *args, **kwargs):
- # Add data to the context here...
- return context
diff --git a/horizon/test/test_dashboards/dogs/static/dogs/css/dogs.css b/horizon/test/test_dashboards/dogs/static/dogs/css/dogs.css
deleted file mode 100644
index 3174af76..00000000
--- a/horizon/test/test_dashboards/dogs/static/dogs/css/dogs.css
+++ /dev/null
@@ -1 +0,0 @@
-/* Additional CSS for dogs. */
diff --git a/horizon/test/test_dashboards/dogs/static/dogs/js/dogs.js b/horizon/test/test_dashboards/dogs/static/dogs/js/dogs.js
deleted file mode 100644
index f1cf07b5..00000000
--- a/horizon/test/test_dashboards/dogs/static/dogs/js/dogs.js
+++ /dev/null
@@ -1 +0,0 @@
-/* Additional JavaScript for dogs. */
diff --git a/horizon/test/test_dashboards/dogs/templates/dogs/base.html b/horizon/test/test_dashboards/dogs/templates/dogs/base.html
deleted file mode 100644
index d4bfcee0..00000000
--- a/horizon/test/test_dashboards/dogs/templates/dogs/base.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-
-{% block sidebar %}
- {% include 'horizon/common/_sidebar.html' %}
-{% endblock %}
-
-{% block main %}
- {% include "horizon/_messages.html" %}
- {% block dogs_main %}{% endblock %}
-{% endblock %}
-
diff --git a/horizon/test/tests/__init__.py b/horizon/test/tests/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/test/tests/__init__.py
+++ /dev/null
diff --git a/horizon/test/tests/base.py b/horizon/test/tests/base.py
deleted file mode 100644
index fd942fd0..00000000
--- a/horizon/test/tests/base.py
+++ /dev/null
@@ -1,390 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Openstack, LLC
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf import settings
-from django.contrib.auth.models import User
-from django.core import urlresolvers
-from django.utils.importlib import import_module
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-from horizon import base
-from horizon import conf
-from horizon.test import helpers as test
-from horizon.test.test_dashboards.cats.dashboard import Cats
-from horizon.test.test_dashboards.cats.kittens.panel import Kittens
-from horizon.test.test_dashboards.cats.tigers.panel import Tigers
-from horizon.test.test_dashboards.dogs.dashboard import Dogs
-from horizon.test.test_dashboards.dogs.puppies.panel import Puppies
-
-
-class MyDash(horizon.Dashboard):
- name = _("My Dashboard")
- slug = "mydash"
- default_panel = "myslug"
-
-
-class MyPanel(horizon.Panel):
- name = _("My Panel")
- slug = "myslug"
- urls = 'horizon.test.test_dashboards.cats.kittens.urls'
-
-
-class AdminPanel(horizon.Panel):
- name = _("Admin Panel")
- slug = "admin_panel"
- permissions = ("horizon.test",)
- urls = 'horizon.test.test_dashboards.cats.kittens.urls'
-
-
-class BaseHorizonTests(test.TestCase):
-
- def setUp(self):
- super(BaseHorizonTests, self).setUp()
- # Adjust our horizon config and register our custom dashboards/panels.
- self.old_default_dash = settings.HORIZON_CONFIG['default_dashboard']
- settings.HORIZON_CONFIG['default_dashboard'] = 'cats'
- self.old_dashboards = settings.HORIZON_CONFIG['dashboards']
- settings.HORIZON_CONFIG['dashboards'] = ('cats', 'dogs')
- base.Horizon.register(Cats)
- base.Horizon.register(Dogs)
- Cats.register(Kittens)
- Cats.register(Tigers)
- Dogs.register(Puppies)
- # Trigger discovery, registration, and URLconf generation if it
- # hasn't happened yet.
- base.Horizon._urls()
- # Store our original dashboards
- self._discovered_dashboards = base.Horizon._registry.keys()
- # Gather up and store our original panels for each dashboard
- self._discovered_panels = {}
- for dash in self._discovered_dashboards:
- panels = base.Horizon._registry[dash]._registry.keys()
- self._discovered_panels[dash] = panels
-
- def tearDown(self):
- super(BaseHorizonTests, self).tearDown()
- # Restore our settings
- settings.HORIZON_CONFIG['default_dashboard'] = self.old_default_dash
- settings.HORIZON_CONFIG['dashboards'] = self.old_dashboards
- # Destroy our singleton and re-create it.
- base.HorizonSite._instance = None
- del base.Horizon
- base.Horizon = base.HorizonSite()
- # Reload the convenience references to Horizon stored in __init__
- reload(import_module("horizon"))
- # Re-register our original dashboards and panels.
- # This is necessary because autodiscovery only works on the first
- # import, and calling reload introduces innumerable additional
- # problems. Manual re-registration is the only good way for testing.
- self._discovered_dashboards.remove(Cats)
- self._discovered_dashboards.remove(Dogs)
- for dash in self._discovered_dashboards:
- base.Horizon.register(dash)
- for panel in self._discovered_panels[dash]:
- dash.register(panel)
-
- def _reload_urls(self):
- '''
- Clears out the URL caches, reloads the root urls module, and
- re-triggers the autodiscovery mechanism for Horizon. Allows URLs
- to be re-calculated after registering new dashboards. Useful
- only for testing and should never be used on a live site.
- '''
- urlresolvers.clear_url_caches()
- reload(import_module(settings.ROOT_URLCONF))
- base.Horizon._urls()
-
-
-class HorizonTests(BaseHorizonTests):
-
- def test_registry(self):
- """ Verify registration and autodiscovery work correctly.
-
- Please note that this implicitly tests that autodiscovery works
- by virtue of the fact that the dashboards listed in
- ``settings.INSTALLED_APPS`` are loaded from the start.
- """
- # Registration
- self.assertEqual(len(base.Horizon._registry), 2)
- horizon.register(MyDash)
- self.assertEqual(len(base.Horizon._registry), 3)
- with self.assertRaises(ValueError):
- horizon.register(MyPanel)
- with self.assertRaises(ValueError):
- horizon.register("MyPanel")
-
- # Retrieval
- my_dash_instance_by_name = horizon.get_dashboard("mydash")
- self.assertTrue(isinstance(my_dash_instance_by_name, MyDash))
- my_dash_instance_by_class = horizon.get_dashboard(MyDash)
- self.assertEqual(my_dash_instance_by_name, my_dash_instance_by_class)
- with self.assertRaises(base.NotRegistered):
- horizon.get_dashboard("fake")
- self.assertQuerysetEqual(horizon.get_dashboards(),
- ['<Dashboard: cats>',
- '<Dashboard: dogs>',
- '<Dashboard: mydash>'])
-
- # Removal
- self.assertEqual(len(base.Horizon._registry), 3)
- horizon.unregister(MyDash)
- self.assertEqual(len(base.Horizon._registry), 2)
- with self.assertRaises(base.NotRegistered):
- horizon.get_dashboard(MyDash)
-
- def test_site(self):
- self.assertEqual(unicode(base.Horizon), "Horizon")
- self.assertEqual(repr(base.Horizon), "<Site: horizon>")
- dash = base.Horizon.get_dashboard('cats')
- self.assertEqual(base.Horizon.get_default_dashboard(), dash)
- test_user = User()
- self.assertEqual(base.Horizon.get_user_home(test_user),
- dash.get_absolute_url())
-
- def test_dashboard(self):
- cats = horizon.get_dashboard("cats")
- self.assertEqual(cats._registered_with, base.Horizon)
- self.assertQuerysetEqual(cats.get_panels(),
- ['<Panel: kittens>',
- '<Panel: tigers>'])
- self.assertEqual(cats.get_absolute_url(), "/cats/")
- self.assertEqual(cats.name, "Cats")
-
- # Test registering a module with a dashboard that defines panels
- # as a panel group.
- cats.register(MyPanel)
- self.assertQuerysetEqual(cats.get_panel_groups()['other'],
- ['<Panel: myslug>'])
-
- # Test that panels defined as a tuple still return a PanelGroup
- dogs = horizon.get_dashboard("dogs")
- self.assertQuerysetEqual(dogs.get_panel_groups().values(),
- ['<PanelGroup: default>'])
-
- # Test registering a module with a dashboard that defines panels
- # as a tuple.
- dogs = horizon.get_dashboard("dogs")
- dogs.register(MyPanel)
- self.assertQuerysetEqual(dogs.get_panels(),
- ['<Panel: puppies>',
- '<Panel: myslug>'])
-
- def test_panels(self):
- cats = horizon.get_dashboard("cats")
- tigers = cats.get_panel("tigers")
- self.assertEqual(tigers._registered_with, cats)
- self.assertEqual(tigers.get_absolute_url(), "/cats/tigers/")
-
- def test_index_url_name(self):
- cats = horizon.get_dashboard("cats")
- tigers = cats.get_panel("tigers")
- tigers.index_url_name = "does_not_exist"
- with self.assertRaises(urlresolvers.NoReverseMatch):
- tigers.get_absolute_url()
- tigers.index_url_name = "index"
- self.assertEqual(tigers.get_absolute_url(), "/cats/tigers/")
-
- def test_lazy_urls(self):
- urlpatterns = horizon.urls[0]
- self.assertTrue(isinstance(urlpatterns, base.LazyURLPattern))
- # The following two methods simply should not raise any exceptions
- iter(urlpatterns)
- reversed(urlpatterns)
-
- def test_horizon_test_isolation_1(self):
- """ Isolation Test Part 1: sets a value. """
- cats = horizon.get_dashboard("cats")
- cats.evil = True
-
- def test_horizon_test_isolation_2(self):
- """ Isolation Test Part 2: The value set in part 1 should be gone. """
- cats = horizon.get_dashboard("cats")
- self.assertFalse(hasattr(cats, "evil"))
-
- def test_public(self):
- dogs = horizon.get_dashboard("dogs")
- # Known to have no restrictions on it other than being logged in.
- puppies = dogs.get_panel("puppies")
- url = puppies.get_absolute_url()
-
- # Get a clean, logged out client instance.
- self.client.logout()
-
- resp = self.client.get(url)
- redirect_url = "?".join(['http://testserver' + settings.LOGIN_URL,
- "next=%s" % url])
- self.assertRedirects(resp, redirect_url)
-
- # Simulate ajax call
- resp = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
- # Response should be HTTP 401 with redirect header
- self.assertEquals(resp.status_code, 401)
- self.assertEquals(resp["X-Horizon-Location"],
- redirect_url)
-
- def test_required_permissions(self):
- dash = horizon.get_dashboard("cats")
- panel = dash.get_panel('tigers')
-
- # Non-admin user
- self.assertQuerysetEqual(self.user.get_all_permissions(), [])
-
- resp = self.client.get(panel.get_absolute_url())
- self.assertEqual(resp.status_code, 302)
-
- resp = self.client.get(panel.get_absolute_url(),
- follow=False,
- HTTP_X_REQUESTED_WITH='XMLHttpRequest')
- self.assertEqual(resp.status_code, 401)
-
- # Test insufficient permissions for logged-in user
- resp = self.client.get(panel.get_absolute_url(), follow=True)
- self.assertEqual(resp.status_code, 200)
- self.assertTemplateUsed(resp, "auth/login.html")
- self.assertContains(resp, "Login as different user", 1, 200)
-
- # Set roles for admin user
- self.set_permissions(permissions=['test'])
-
- resp = self.client.get(panel.get_absolute_url())
- self.assertEqual(resp.status_code, 200)
-
- # Test modal form
- resp = self.client.get(panel.get_absolute_url(),
- follow=False,
- HTTP_X_REQUESTED_WITH='XMLHttpRequest')
- self.assertEqual(resp.status_code, 200)
-
- def test_ssl_redirect_by_proxy(self):
- dogs = horizon.get_dashboard("dogs")
- puppies = dogs.get_panel("puppies")
- url = puppies.get_absolute_url()
- redirect_url = "?".join([settings.LOGIN_URL,
- "next=%s" % url])
-
- self.client.logout()
- resp = self.client.get(url)
- self.assertRedirects(resp, redirect_url)
-
- # Set SSL settings for test server
- settings.SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL',
- 'https')
-
- resp = self.client.get(url, HTTP_X_FORWARDED_PROTOCOL="https")
- self.assertEqual(resp.status_code, 302)
- self.assertEqual(resp['location'],
- 'https://testserver:80%s' % redirect_url)
-
- # Restore settings
- settings.SECURE_PROXY_SSL_HEADER = None
-
-
-class CustomPanelTests(BaseHorizonTests):
-
- """ Test customization of dashboards and panels
- using 'customization_module' to HORIZON_CONFIG.
- """
-
- def setUp(self):
- settings.HORIZON_CONFIG['customization_module'] = \
- 'horizon.test.customization.cust_test1'
- # refresh config
- conf.HORIZON_CONFIG._setup()
- super(CustomPanelTests, self).setUp()
-
- def tearDown(self):
- # Restore dash
- cats = horizon.get_dashboard("cats")
- cats.name = _("Cats")
- horizon.register(Dogs)
- self._discovered_dashboards.append(Dogs)
- Dogs.register(Puppies)
- Cats.register(Tigers)
- super(CustomPanelTests, self).tearDown()
- settings.HORIZON_CONFIG.pop('customization_module')
- # refresh config
- conf.HORIZON_CONFIG._setup()
-
- def test_customize_dashboard(self):
- cats = horizon.get_dashboard("cats")
- self.assertEqual(cats.name, "WildCats")
- self.assertQuerysetEqual(cats.get_panels(),
- ['<Panel: kittens>'])
- with self.assertRaises(base.NotRegistered):
- horizon.get_dashboard("dogs")
-
-
-class CustomPermissionsTests(BaseHorizonTests):
-
- """ Test customization of permissions on panels
- using 'customization_module' to HORIZON_CONFIG.
- """
-
- def setUp(self):
- settings.HORIZON_CONFIG['customization_module'] = \
- 'horizon.test.customization.cust_test2'
- # refresh config
- conf.HORIZON_CONFIG._setup()
- super(CustomPermissionsTests, self).setUp()
-
- def tearDown(self):
- # Restore permissions
- dogs = horizon.get_dashboard("dogs")
- puppies = dogs.get_panel("puppies")
- puppies.permissions = tuple([])
- super(CustomPermissionsTests, self).tearDown()
- settings.HORIZON_CONFIG.pop('customization_module')
- # refresh config
- conf.HORIZON_CONFIG._setup()
-
- def test_customized_permissions(self):
- dogs = horizon.get_dashboard("dogs")
- panel = dogs.get_panel('puppies')
-
- # Non-admin user
- self.assertQuerysetEqual(self.user.get_all_permissions(), [])
-
- resp = self.client.get(panel.get_absolute_url())
- self.assertEqual(resp.status_code, 302)
-
- resp = self.client.get(panel.get_absolute_url(),
- follow=False,
- HTTP_X_REQUESTED_WITH='XMLHttpRequest')
- self.assertEqual(resp.status_code, 401)
-
- # Test customized permissions for logged-in user
- resp = self.client.get(panel.get_absolute_url(), follow=True)
- self.assertEqual(resp.status_code, 200)
- self.assertTemplateUsed(resp, "auth/login.html")
- self.assertContains(resp, "Login as different user", 1, 200)
-
- # Set roles for admin user
- self.set_permissions(permissions=['test'])
-
- resp = self.client.get(panel.get_absolute_url())
- self.assertEqual(resp.status_code, 200)
-
- # Test modal form
- resp = self.client.get(panel.get_absolute_url(),
- follow=False,
- HTTP_X_REQUESTED_WITH='XMLHttpRequest')
- self.assertEqual(resp.status_code, 200)
diff --git a/horizon/test/tests/messages.py b/horizon/test/tests/messages.py
deleted file mode 100644
index 8548ff4d..00000000
--- a/horizon/test/tests/messages.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import json
-
-from django import http
-from django.utils.encoding import force_unicode
-from django.utils.safestring import mark_safe
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import messages
-from horizon import middleware
-from horizon.test import helpers as test
-
-
-class MessageTests(test.TestCase):
- def test_middleware_header(self):
- req = self.request
- string = _("Giant ants are attacking San Francisco!")
- expected = ["error", force_unicode(string), ""]
- self.assertTrue("async_messages" in req.horizon)
- self.assertItemsEqual(req.horizon['async_messages'], [])
- req.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
- messages.error(req, string)
- self.assertItemsEqual(req.horizon['async_messages'], [expected])
- res = http.HttpResponse()
- res = middleware.HorizonMiddleware().process_response(req, res)
- self.assertEqual(res['X-Horizon-Messages'],
- json.dumps([expected]))
-
- def test_safe_message(self):
- req = self.request
- string = mark_safe(_("We are now safe from ants! Go <a>here</a>!"))
- expected = ["error", force_unicode(string), " safe"]
- self.assertTrue("async_messages" in req.horizon)
- self.assertItemsEqual(req.horizon['async_messages'], [])
- req.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
- messages.error(req, string)
- self.assertItemsEqual(req.horizon['async_messages'], [expected])
- res = http.HttpResponse()
- res = middleware.HorizonMiddleware().process_response(req, res)
- self.assertEqual(res['X-Horizon-Messages'],
- json.dumps([expected]))
diff --git a/horizon/test/tests/middleware.py b/horizon/test/tests/middleware.py
deleted file mode 100644
index 958e4233..00000000
--- a/horizon/test/tests/middleware.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 OpenStack LLC.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf import settings
-
-from horizon import exceptions
-from horizon import middleware
-from horizon.test import helpers as test
-
-
-class MiddlewareTests(test.TestCase):
- def test_redirect_login_fail_to_login(self):
- url = settings.LOGIN_URL
- request = self.factory.post(url)
-
- mw = middleware.HorizonMiddleware()
- resp = mw.process_exception(request, exceptions.NotAuthorized())
- resp.client = self.client
-
- self.assertRedirects(resp, url)
diff --git a/horizon/test/tests/selenium.py b/horizon/test/tests/selenium.py
deleted file mode 100644
index efe04395..00000000
--- a/horizon/test/tests/selenium.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from horizon.test import helpers as test
-
-
-class BrowserTests(test.SeleniumTestCase):
- def test_qunit(self):
- self.selenium.get("%s%s" % (self.live_server_url, "/qunit/"))
- wait = self.ui.WebDriverWait(self.selenium, 10)
-
- def qunit_done(driver):
- text = driver.find_element_by_id("qunit-testresult").text
- return "Tests completed" in text
-
- wait.until(qunit_done)
- failed = self.selenium.find_element_by_class_name("failed")
- self.assertEqual(int(failed.text), 0)
diff --git a/horizon/test/tests/tables.py b/horizon/test/tests/tables.py
deleted file mode 100644
index d17dc95d..00000000
--- a/horizon/test/tests/tables.py
+++ /dev/null
@@ -1,755 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django import http
-from django import shortcuts
-from django.utils.translation import ugettext_lazy as _
-
-from mox import IsA
-
-from horizon import tables
-from horizon.tables import views as table_views
-from horizon.test import helpers as test
-
-
-class FakeObject(object):
- def __init__(self, id, name, value, status, optional=None, excluded=None):
- self.id = id
- self.name = name
- self.value = value
- self.status = status
- self.optional = optional
- self.excluded = excluded
- self.extra = "extra"
-
- def __repr__(self):
- return "<%s: %s>" % (self.__class__.__name__, self.name)
-
-
-TEST_DATA = (
- FakeObject('1', 'object_1', 'value_1', 'up', 'optional_1', 'excluded_1'),
- FakeObject('2', 'object_2', '<strong>evil</strong>', 'down', 'optional_2'),
- FakeObject('3', 'object_3', 'value_3', 'up'),
-)
-
-TEST_DATA_2 = (
- FakeObject('1', 'object_1', 'value_1', 'down', 'optional_1', 'excluded_1'),
-)
-
-TEST_DATA_3 = (
- FakeObject('1', 'object_1', 'value_1', 'up', 'optional_1', 'excluded_1'),
-)
-
-TEST_DATA_4 = (
- FakeObject('1', 'object_1', 2, 'up'),
- FakeObject('2', 'object_2', 4, 'up'),
-)
-
-TEST_DATA_5 = (
- FakeObject('1', 'object_1', 'A Value That is longer than 35 characters!',
- 'down', 'optional_1'),
-)
-
-
-class MyLinkAction(tables.LinkAction):
- name = "login"
- verbose_name = "Log In"
- url = "login"
- attrs = {
- "class": "ajax-modal",
- }
-
- def get_link_url(self, datum=None, *args, **kwargs):
- return reverse(self.url)
-
-
-class MyAction(tables.Action):
- name = "delete"
- verbose_name = "Delete Me"
- verbose_name_plural = "Delete Them"
-
- def allowed(self, request, obj=None):
- return getattr(obj, 'status', None) != 'down'
-
- def handle(self, data_table, request, object_ids):
- return shortcuts.redirect('http://example.com/?ids=%s'
- % ",".join(object_ids))
-
-
-class MyColumn(tables.Column):
- pass
-
-
-class MyRow(tables.Row):
- ajax = True
-
- @classmethod
- def get_data(cls, request, obj_id):
- return TEST_DATA_2[0]
-
-
-class MyBatchAction(tables.BatchAction):
- name = "batch"
- action_present = _("Batch")
- action_past = _("Batched")
- data_type_singular = _("Item")
- data_type_plural = _("Items")
-
- def action(self, request, object_ids):
- pass
-
-
-class MyToggleAction(tables.BatchAction):
- name = "toggle"
- action_present = (_("Down"), _("Up"))
- action_past = (_("Downed"), _("Upped"))
- data_type_singular = _("Item")
- data_type_plural = _("Items")
-
- def allowed(self, request, obj=None):
- if not obj:
- return False
- self.down = getattr(obj, 'status', None) == 'down'
- if self.down:
- self.current_present_action = 1
- return self.down or getattr(obj, 'status', None) == 'up'
-
- def action(self, request, object_ids):
- if self.down:
- #up it
- self.current_past_action = 1
-
-
-class MyFilterAction(tables.FilterAction):
- def filter(self, table, objs, filter_string):
- q = filter_string.lower()
-
- def comp(obj):
- if q in obj.name.lower():
- return True
- return False
-
- return filter(comp, objs)
-
-
-def get_name(obj):
- return "custom %s" % obj.name
-
-
-def get_link(obj):
- return reverse('login')
-
-
-class MyTable(tables.DataTable):
- id = tables.Column('id', hidden=True, sortable=False)
- name = tables.Column(get_name, verbose_name="Verbose Name", sortable=True)
- value = tables.Column('value',
- sortable=True,
- link='http://example.com/',
- attrs={'class': 'green blue'},
- summation="average",
- truncate=35,
- link_classes=('link-modal',))
- status = tables.Column('status', link=get_link)
- optional = tables.Column('optional', empty_value='N/A')
- excluded = tables.Column('excluded')
-
- class Meta:
- name = "my_table"
- verbose_name = "My Table"
- status_columns = ["status"]
- columns = ('id', 'name', 'value', 'optional', 'status')
- row_class = MyRow
- column_class = MyColumn
- table_actions = (MyFilterAction, MyAction, MyBatchAction)
- row_actions = (MyAction, MyLinkAction, MyBatchAction, MyToggleAction)
-
-
-class NoActionsTable(tables.DataTable):
- id = tables.Column('id')
-
- class Meta:
- name = "no_actions_table"
- verbose_name = _("No Actions Table")
- table_actions = ()
- row_actions = ()
-
-
-class DataTableTests(test.TestCase):
- def test_table_instantiation(self):
- """ Tests everything that happens when the table is instantiated. """
- self.table = MyTable(self.request, TEST_DATA)
- # Properties defined on the table
- self.assertEqual(self.table.data, TEST_DATA)
- self.assertEqual(self.table.name, "my_table")
- # Verify calculated options that weren't specified explicitly
- self.assertTrue(self.table._meta.actions_column)
- self.assertTrue(self.table._meta.multi_select)
- # Test for verbose_name
- self.assertEqual(unicode(self.table), u"My Table")
- # Column ordering and exclusion.
- # This should include auto-columns for multi_select and actions,
- # but should not contain the excluded column.
- # Additionally, auto-generated columns should use the custom
- # column class specified on the table.
- self.assertQuerysetEqual(self.table.columns.values(),
- ['<MyColumn: multi_select>',
- '<Column: id>',
- '<Column: name>',
- '<Column: value>',
- '<Column: optional>',
- '<Column: status>',
- '<MyColumn: actions>'])
- # Actions (these also test ordering)
- self.assertQuerysetEqual(self.table.base_actions.values(),
- ['<MyBatchAction: batch>',
- '<MyAction: delete>',
- '<MyFilterAction: filter>',
- '<MyLinkAction: login>',
- '<MyToggleAction: toggle>'])
- self.assertQuerysetEqual(self.table.get_table_actions(),
- ['<MyFilterAction: filter>',
- '<MyAction: delete>',
- '<MyBatchAction: batch>'])
- self.assertQuerysetEqual(self.table.get_row_actions(TEST_DATA[0]),
- ['<MyAction: delete>',
- '<MyLinkAction: login>',
- '<MyBatchAction: batch>',
- '<MyToggleAction: toggle>'])
- # Auto-generated columns
- multi_select = self.table.columns['multi_select']
- self.assertEqual(multi_select.auto, "multi_select")
- self.assertEqual(multi_select.get_final_attrs().get('class', ""),
- "multi_select_column")
- actions = self.table.columns['actions']
- self.assertEqual(actions.auto, "actions")
- self.assertEqual(actions.get_final_attrs().get('class', ""),
- "actions_column")
-
- def test_table_force_no_multiselect(self):
- class TempTable(MyTable):
- class Meta:
- columns = ('id',)
- table_actions = (MyFilterAction, MyAction,)
- row_actions = (MyAction, MyLinkAction,)
- multi_select = False
- self.table = TempTable(self.request, TEST_DATA)
- self.assertQuerysetEqual(self.table.columns.values(),
- ['<Column: id>',
- '<Column: actions>'])
-
- def test_table_force_no_actions_column(self):
- class TempTable(MyTable):
- class Meta:
- columns = ('id',)
- table_actions = (MyFilterAction, MyAction,)
- row_actions = (MyAction, MyLinkAction,)
- actions_column = False
- self.table = TempTable(self.request, TEST_DATA)
- self.assertQuerysetEqual(self.table.columns.values(),
- ['<Column: multi_select>',
- '<Column: id>'])
-
- def test_table_natural_no_actions_column(self):
- class TempTable(MyTable):
- class Meta:
- columns = ('id',)
- table_actions = (MyFilterAction, MyAction,)
- self.table = TempTable(self.request, TEST_DATA)
- self.assertQuerysetEqual(self.table.columns.values(),
- ['<Column: multi_select>',
- '<Column: id>'])
-
- def test_table_natural_no_multiselect(self):
- class TempTable(MyTable):
- class Meta:
- columns = ('id',)
- row_actions = (MyAction, MyLinkAction,)
- self.table = TempTable(self.request, TEST_DATA)
- self.assertQuerysetEqual(self.table.columns.values(),
- ['<Column: id>',
- '<Column: actions>'])
-
- def test_table_column_inheritance(self):
- class TempTable(MyTable):
- extra = tables.Column('extra')
-
- class Meta:
- name = "temp_table"
- table_actions = (MyFilterAction, MyAction,)
- row_actions = (MyAction, MyLinkAction,)
-
- self.table = TempTable(self.request, TEST_DATA)
- self.assertQuerysetEqual(self.table.columns.values(),
- ['<Column: multi_select>',
- '<Column: id>',
- '<Column: name>',
- '<Column: value>',
- '<Column: status>',
- '<Column: optional>',
- '<Column: excluded>',
- '<Column: extra>',
- '<Column: actions>'])
-
- def test_table_construction(self):
- self.table = MyTable(self.request, TEST_DATA)
- # Verify we retrieve the right columns for headers
- columns = self.table.get_columns()
- self.assertQuerysetEqual(columns, ['<MyColumn: multi_select>',
- '<Column: id>',
- '<Column: name>',
- '<Column: value>',
- '<Column: optional>',
- '<Column: status>',
- '<MyColumn: actions>'])
- # Verify we retrieve the right rows from our data
- rows = self.table.get_rows()
- self.assertQuerysetEqual(rows, ['<MyRow: my_table__row__1>',
- '<MyRow: my_table__row__2>',
- '<MyRow: my_table__row__3>'])
- # Verify each row contains the right cells
- self.assertQuerysetEqual(rows[0].get_cells(),
- ['<Cell: multi_select, my_table__row__1>',
- '<Cell: id, my_table__row__1>',
- '<Cell: name, my_table__row__1>',
- '<Cell: value, my_table__row__1>',
- '<Cell: optional, my_table__row__1>',
- '<Cell: status, my_table__row__1>',
- '<Cell: actions, my_table__row__1>'])
-
- def test_table_column(self):
- self.table = MyTable(self.request, TEST_DATA)
- row = self.table.get_rows()[0]
- row3 = self.table.get_rows()[2]
- id_col = self.table.columns['id']
- name_col = self.table.columns['name']
- value_col = self.table.columns['value']
- # transform
- self.assertEqual(row.cells['id'].data, '1') # Standard attr access
- self.assertEqual(row.cells['name'].data, 'custom object_1') # Callable
- # name and verbose_name
- self.assertEqual(unicode(id_col), "Id")
- self.assertEqual(unicode(name_col), "Verbose Name")
- # sortable
- self.assertEqual(id_col.sortable, False)
- self.assertNotIn("sortable", id_col.get_final_attrs().get('class', ""))
- self.assertEqual(name_col.sortable, True)
- self.assertIn("sortable", name_col.get_final_attrs().get('class', ""))
- # hidden
- self.assertEqual(id_col.hidden, True)
- self.assertIn("hide", id_col.get_final_attrs().get('class', ""))
- self.assertEqual(name_col.hidden, False)
- self.assertNotIn("hide", name_col.get_final_attrs().get('class', ""))
- # link, link_classes and get_link_url
- self.assertIn('href="http://example.com/"', row.cells['value'].value)
- self.assertIn('class="link-modal"', row.cells['value'].value)
- self.assertIn('href="/auth/login/"', row.cells['status'].value)
- # empty_value
- self.assertEqual(row3.cells['optional'].value, "N/A")
- # classes
- self.assertEqual(value_col.get_final_attrs().get('class', ""),
- "green blue sortable anchor normal_column")
- # status
- cell_status = row.cells['status'].status
- self.assertEqual(cell_status, True)
- self.assertEqual(row.cells['status'].get_status_class(cell_status),
- 'status_up')
- # status_choices
- id_col.status = True
- id_col.status_choices = (('1', False), ('2', True), ('3', None))
- cell_status = row.cells['id'].status
- self.assertEqual(cell_status, False)
- self.assertEqual(row.cells['id'].get_status_class(cell_status),
- 'status_down')
- cell_status = row3.cells['id'].status
- self.assertEqual(cell_status, None)
- self.assertEqual(row.cells['id'].get_status_class(cell_status),
- 'status_unknown')
-
- # Ensure data is not cached on the column across table instances
- self.table = MyTable(self.request, TEST_DATA_2)
- row = self.table.get_rows()[0]
- self.assertTrue("down" in row.cells['status'].value)
-
- def test_table_row(self):
- self.table = MyTable(self.request, TEST_DATA)
- row = self.table.get_rows()[0]
- self.assertEqual(row.table, self.table)
- self.assertEqual(row.datum, TEST_DATA[0])
- self.assertEqual(row.id, 'my_table__row__1')
- # Verify row status works even if status isn't set on the column
- self.assertEqual(row.status, True)
- self.assertEqual(row.status_class, 'status_up')
- # Check the cells as well
- cell_status = row.cells['status'].status
- self.assertEqual(cell_status, True)
- self.assertEqual(row.cells['status'].get_status_class(cell_status),
- 'status_up')
-
- def test_table_column_truncation(self):
- self.table = MyTable(self.request, TEST_DATA_5)
- row = self.table.get_rows()[0]
-
- self.assertEqual(len(row.cells['value'].data), 35)
- self.assertEqual(row.cells['value'].data,
- u'A Value That is longer than 35 c...')
-
- def test_table_rendering(self):
- self.table = MyTable(self.request, TEST_DATA)
- # Table actions
- table_actions = self.table.render_table_actions()
- resp = http.HttpResponse(table_actions)
- self.assertContains(resp, "table_search", 1)
- self.assertContains(resp, "my_table__filter__q", 1)
- self.assertContains(resp, "my_table__delete", 1)
- self.assertContains(resp, 'id="my_table__action_delete"', 1)
- # Row actions
- row_actions = self.table.render_row_actions(TEST_DATA[0])
- resp = http.HttpResponse(row_actions)
- self.assertContains(resp, "<li", 3)
- self.assertContains(resp, "my_table__delete__1", 1)
- self.assertContains(resp, "my_table__toggle__1", 1)
- self.assertContains(resp, "/auth/login/", 1)
- self.assertContains(resp, "ajax-modal", 1)
- self.assertContains(resp, 'id="my_table__row_1__action_delete"', 1)
- # Whole table
- resp = http.HttpResponse(self.table.render())
- self.assertContains(resp, '<table id="my_table"', 1)
- self.assertContains(resp, '<th ', 8)
- self.assertContains(resp, 'id="my_table__row__1"', 1)
- self.assertContains(resp, 'id="my_table__row__2"', 1)
- self.assertContains(resp, 'id="my_table__row__3"', 1)
- update_string = "action=row_update&amp;table=my_table&amp;obj_id="
- self.assertContains(resp, update_string, 3)
- self.assertContains(resp, "data-update-interval", 3)
- # Verify our XSS protection
- self.assertContains(resp, '<a href="http://example.com/" '
- 'class="link-modal">'
- '&lt;strong&gt;evil&lt;/strong&gt;</a>', 1)
- # Filter = False hides the search box
- self.table._meta.filter = False
- table_actions = self.table.render_table_actions()
- resp = http.HttpResponse(table_actions)
- self.assertContains(resp, "table_search", 0)
-
- def test_table_actions(self):
- # Single object action
- action_string = "my_table__delete__1"
- req = self.factory.post('/my_url/', {'action': action_string})
- self.table = MyTable(req, TEST_DATA)
- self.assertEqual(self.table.parse_action(action_string),
- ('my_table', 'delete', '1'))
- handled = self.table.maybe_handle()
- self.assertEqual(handled.status_code, 302)
- self.assertEqual(handled["location"], "http://example.com/?ids=1")
-
- # Batch action (without toggle) conjugation behavior
- req = self.factory.get('/my_url/')
- self.table = MyTable(req, TEST_DATA_3)
- toggle_action = self.table.get_row_actions(TEST_DATA_3[0])[2]
- self.assertEqual(unicode(toggle_action.verbose_name), "Batch Item")
-
- # Single object toggle action
- # GET page - 'up' to 'down'
- req = self.factory.get('/my_url/')
- self.table = MyTable(req, TEST_DATA_3)
- self.assertEqual(len(self.table.get_row_actions(TEST_DATA_3[0])), 4)
- toggle_action = self.table.get_row_actions(TEST_DATA_3[0])[3]
- self.assertEqual(unicode(toggle_action.verbose_name), "Down Item")
-
- # Toggle from status 'up' to 'down'
- # POST page
- action_string = "my_table__toggle__1"
- req = self.factory.post('/my_url/', {'action': action_string})
- self.table = MyTable(req, TEST_DATA)
- self.assertEqual(self.table.parse_action(action_string),
- ('my_table', 'toggle', '1'))
- handled = self.table.maybe_handle()
- self.assertEqual(handled.status_code, 302)
- self.assertEqual(handled["location"], "/my_url/")
- self.assertEqual(list(req._messages)[0].message,
- u"Downed Item: object_1")
-
- # Toggle from status 'down' to 'up'
- # GET page - 'down' to 'up'
- req = self.factory.get('/my_url/')
- self.table = MyTable(req, TEST_DATA_2)
- self.assertEqual(len(self.table.get_row_actions(TEST_DATA_2[0])), 3)
- toggle_action = self.table.get_row_actions(TEST_DATA_2[0])[2]
- self.assertEqual(unicode(toggle_action.verbose_name), "Up Item")
-
- # POST page
- action_string = "my_table__toggle__2"
- req = self.factory.post('/my_url/', {'action': action_string})
- self.table = MyTable(req, TEST_DATA)
- self.assertEqual(self.table.parse_action(action_string),
- ('my_table', 'toggle', '2'))
- handled = self.table.maybe_handle()
- self.assertEqual(handled.status_code, 302)
- self.assertEqual(handled["location"], "/my_url/")
- self.assertEqual(list(req._messages)[0].message,
- u"Upped Item: object_2")
-
- # Multiple object action
- action_string = "my_table__delete"
- req = self.factory.post('/my_url/', {'action': action_string,
- 'object_ids': [1, 2]})
- self.table = MyTable(req, TEST_DATA)
- self.assertEqual(self.table.parse_action(action_string),
- ('my_table', 'delete', None))
- handled = self.table.maybe_handle()
- self.assertEqual(handled.status_code, 302)
- self.assertEqual(handled["location"], "http://example.com/?ids=1,2")
-
- # Action with nothing selected
- req = self.factory.post('/my_url/', {'action': action_string})
- self.table = MyTable(req, TEST_DATA)
- self.assertEqual(self.table.parse_action(action_string),
- ('my_table', 'delete', None))
- handled = self.table.maybe_handle()
- self.assertEqual(handled, None)
- self.assertEqual(list(req._messages)[0].message,
- "Please select a row before taking that action.")
-
- # Action with specific id and multiple ids favors single id
- action_string = "my_table__delete__3"
- req = self.factory.post('/my_url/', {'action': action_string,
- 'object_ids': [1, 2]})
- self.table = MyTable(req, TEST_DATA)
- self.assertEqual(self.table.parse_action(action_string),
- ('my_table', 'delete', '3'))
- handled = self.table.maybe_handle()
- self.assertEqual(handled.status_code, 302)
- self.assertEqual(handled["location"],
- "http://example.com/?ids=3")
-
- # At least one object in table
- # BatchAction is available
- req = self.factory.get('/my_url/')
- self.table = MyTable(req, TEST_DATA_2)
- self.assertQuerysetEqual(self.table.get_table_actions(),
- ['<MyFilterAction: filter>',
- '<MyAction: delete>',
- '<MyBatchAction: batch>'])
-
- # Zero objects in table
- # BatchAction not available
- req = self.factory.get('/my_url/')
- self.table = MyTable(req, None)
- self.assertQuerysetEqual(self.table.get_table_actions(),
- ['<MyFilterAction: filter>',
- '<MyAction: delete>'])
-
- # Filtering
- action_string = "my_table__filter__q"
- req = self.factory.post('/my_url/', {action_string: '2'})
- self.table = MyTable(req, TEST_DATA)
- handled = self.table.maybe_handle()
- self.assertEqual(handled, None)
- self.assertQuerysetEqual(self.table.filtered_data,
- ['<FakeObject: object_2>'])
-
- # Ensure fitering respects the request method, e.g. no filter here
- req = self.factory.get('/my_url/', {action_string: '2'})
- self.table = MyTable(req, TEST_DATA)
- handled = self.table.maybe_handle()
- self.assertEqual(handled, None)
- self.assertQuerysetEqual(self.table.filtered_data,
- ['<FakeObject: object_1>',
- '<FakeObject: object_2>',
- '<FakeObject: object_3>'])
-
- # Updating and preemptive actions
- params = {"table": "my_table", "action": "row_update", "obj_id": "1"}
- req = self.factory.get('/my_url/',
- params,
- HTTP_X_REQUESTED_WITH='XMLHttpRequest')
- self.table = MyTable(req)
- resp = self.table.maybe_preempt()
- self.assertEqual(resp.status_code, 200)
- # Make sure the data returned differs from the original
- self.assertContains(resp, "my_table__row__1")
- self.assertContains(resp, "status_down")
-
- # Verify that we don't get a response for a valid action with the
- # wrong method.
- params = {"table": "my_table", "action": "delete", "obj_id": "1"}
- req = self.factory.get('/my_url/', params)
- self.table = MyTable(req)
- resp = self.table.maybe_preempt()
- self.assertEqual(resp, None)
- resp = self.table.maybe_handle()
- self.assertEqual(resp, None)
-
- # Verbose names
- table_actions = self.table.get_table_actions()
- self.assertEqual(unicode(table_actions[0].verbose_name), "filter")
- self.assertEqual(unicode(table_actions[1].verbose_name), "Delete Me")
-
- row_actions = self.table.get_row_actions(TEST_DATA[0])
- self.assertEqual(unicode(row_actions[0].verbose_name), "Delete Me")
- self.assertEqual(unicode(row_actions[1].verbose_name), "Log In")
-
- def test_column_uniqueness(self):
- table1 = MyTable(self.request)
- table2 = MyTable(self.request)
- # Regression test for launchpad bug 964345.
- self.assertNotEqual(id(table1), id(table2))
- self.assertNotEqual(id(table1.columns), id(table2.columns))
- t1cols = table1.columns.values()
- t2cols = table2.columns.values()
- self.assertEqual(t1cols[0].name, t2cols[0].name)
- self.assertNotEqual(id(t1cols[0]), id(t2cols[0]))
- self.assertNotEqual(id(t1cols[0].table),
- id(t2cols[0].table))
- self.assertNotEqual(id(t1cols[0].table._data_cache),
- id(t2cols[0].table._data_cache))
-
- def test_summation_row(self):
- # Test with the "average" method.
- table = MyTable(self.request, TEST_DATA_4)
- res = http.HttpResponse(table.render())
- self.assertContains(res, '<tr class="summation"', 1)
- self.assertContains(res, '<td>Summary</td>', 1)
- self.assertContains(res, '<td>3.0</td>', 1)
-
- # Test again with the "sum" method.
- table.columns['value'].summation = "sum"
- res = http.HttpResponse(table.render())
- self.assertContains(res, '<tr class="summation"', 1)
- self.assertContains(res, '<td>Summary</td>', 1)
- self.assertContains(res, '<td>6</td>', 1)
-
- # One last test with no summation.
- table.columns['value'].summation = None
- table.needs_summary_row = False
- res = http.HttpResponse(table.render())
- self.assertNotContains(res, '<tr class="summation"')
- self.assertNotContains(res, '<td>3.0</td>')
- self.assertNotContains(res, '<td>6</td>')
-
- def test_table_action_attributes(self):
- table = MyTable(self.request, TEST_DATA)
- self.assertTrue(table.has_actions)
- self.assertTrue(table.needs_form_wrapper)
- res = http.HttpResponse(table.render())
- self.assertContains(res, "<form")
-
- table = MyTable(self.request, TEST_DATA, needs_form_wrapper=False)
- self.assertTrue(table.has_actions)
- self.assertFalse(table.needs_form_wrapper)
- res = http.HttpResponse(table.render())
- self.assertNotContains(res, "<form")
-
- table = NoActionsTable(self.request, TEST_DATA)
- self.assertFalse(table.has_actions)
- self.assertFalse(table.needs_form_wrapper)
- res = http.HttpResponse(table.render())
- self.assertNotContains(res, "<form")
-
- def test_table_action_object_display_is_none(self):
- action_string = "my_table__toggle__1"
- req = self.factory.post('/my_url/', {'action': action_string})
- self.table = MyTable(req, TEST_DATA)
-
- self.mox.StubOutWithMock(self.table, 'get_object_display')
- self.table.get_object_display(IsA(FakeObject)).AndReturn(None)
- self.mox.ReplayAll()
-
- self.assertEqual(self.table.parse_action(action_string),
- ('my_table', 'toggle', '1'))
- handled = self.table.maybe_handle()
- self.assertEqual(handled.status_code, 302)
- self.assertEqual(handled["location"], "/my_url/")
- self.assertEqual(list(req._messages)[0].message,
- u"Downed Item: N/A")
-
-
-class SingleTableView(table_views.DataTableView):
- table_class = MyTable
- name = _("Single Table")
- slug = "single"
- template_name = "horizon/common/_detail_table.html"
-
- def get_data(self):
- return TEST_DATA
-
-
-class TableWithPermissions(tables.DataTable):
- id = tables.Column('id')
-
- class Meta:
- name = "table_with_permissions"
- permissions = ('horizon.test',)
-
-
-class SingleTableViewWithPermissions(SingleTableView):
- table_class = TableWithPermissions
-
-
-class MultiTableView(tables.MultiTableView):
- table_classes = (TableWithPermissions, MyTable)
-
- def get_table_with_permissions_data(self):
- return TEST_DATA
-
- def get_my_table_data(self):
- return TEST_DATA
-
-
-class DataTableViewTests(test.TestCase):
- def _prepare_view(self, cls, *args, **kwargs):
- req = self.factory.get('/my_url/')
- req.user = self.user
- view = cls()
- view.request = req
- view.args = args
- view.kwargs = kwargs
- return view
-
- def test_data_table_view(self):
- view = self._prepare_view(SingleTableView)
- context = view.get_context_data()
- self.assertEqual(context['table'].__class__,
- SingleTableView.table_class)
-
- def test_data_table_view_not_authorized(self):
- view = self._prepare_view(SingleTableViewWithPermissions)
- context = view.get_context_data()
- self.assertNotIn('table', context)
-
- def test_data_table_view_authorized(self):
- view = self._prepare_view(SingleTableViewWithPermissions)
- self.set_permissions(permissions=['test'])
- context = view.get_context_data()
- self.assertIn('table', context)
- self.assertEqual(context['table'].__class__,
- SingleTableViewWithPermissions.table_class)
-
- def test_multi_table_view_not_authorized(self):
- view = self._prepare_view(MultiTableView)
- context = view.get_context_data()
- self.assertEqual(context['my_table_table'].__class__, MyTable)
- self.assertNotIn('table_with_permissions_table', context)
-
- def test_multi_table_view_authorized(self):
- view = self._prepare_view(MultiTableView)
- self.set_permissions(permissions=['test'])
- context = view.get_context_data()
- self.assertEqual(context['my_table_table'].__class__, MyTable)
- self.assertEqual(context['table_with_permissions_table'].__class__,
- TableWithPermissions)
diff --git a/horizon/test/tests/tabs.py b/horizon/test/tests/tabs.py
deleted file mode 100644
index 346fe581..00000000
--- a/horizon/test/tests/tabs.py
+++ /dev/null
@@ -1,307 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import copy
-
-from django import http
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs as horizon_tabs
-from horizon.test import helpers as test
-
-from horizon.test.tests.tables import MyTable
-from horizon.test.tests.tables import TEST_DATA
-
-
-class BaseTestTab(horizon_tabs.Tab):
- def get_context_data(self, request):
- return {"tab": self}
-
-
-class TabOne(BaseTestTab):
- slug = "tab_one"
- name = _("Tab One")
- template_name = "_tab.html"
-
-
-class TabDelayed(BaseTestTab):
- slug = "tab_delayed"
- name = _("Delayed Tab")
- template_name = "_tab.html"
- preload = False
-
-
-class TabDisabled(BaseTestTab):
- slug = "tab_disabled"
- name = _("Disabled Tab")
- template_name = "_tab.html"
-
- def enabled(self, request):
- return False
-
-
-class TabDisallowed(BaseTestTab):
- slug = "tab_disallowed"
- name = _("Disallowed Tab")
- template_name = "_tab.html"
-
- def allowed(self, request):
- return False
-
-
-class Group(horizon_tabs.TabGroup):
- slug = "tab_group"
- tabs = (TabOne, TabDelayed, TabDisabled, TabDisallowed)
- sticky = True
-
- def tabs_not_available(self):
- self._assert_tabs_not_available = True
-
-
-class TabWithTable(horizon_tabs.TableTab):
- table_classes = (MyTable,)
- name = _("Tab With My Table")
- slug = "tab_with_table"
- template_name = "horizon/common/_detail_table.html"
-
- def get_my_table_data(self):
- return TEST_DATA
-
-
-class RecoverableErrorTab(horizon_tabs.Tab):
- name = _("Recoverable Error Tab")
- slug = "recoverable_error_tab"
- template_name = "_tab.html"
-
- def get_context_data(self, request):
- # Raise a known recoverable error.
- exc = exceptions.AlreadyExists("Recoverable!", horizon_tabs.Tab)
- exc.silence_logging = True
- raise exc
-
-
-class TableTabGroup(horizon_tabs.TabGroup):
- slug = "tab_group"
- tabs = [TabWithTable]
-
-
-class TabWithTableView(horizon_tabs.TabbedTableView):
- tab_group_class = TableTabGroup
- template_name = "tab_group.html"
-
-
-class TabTests(test.TestCase):
- def test_tab_group_basics(self):
- tg = Group(self.request)
-
- # Test tab instantiation/attachement to tab group, and get_tabs method
- tabs = tg.get_tabs()
- # "tab_disallowed" should NOT be in this list.
- self.assertQuerysetEqual(tabs, ['<TabOne: tab_one>',
- '<TabDelayed: tab_delayed>',
- '<TabDisabled: tab_disabled>'])
- # Test get_id
- self.assertEqual(tg.get_id(), "tab_group")
- # get_default_classes
- self.assertEqual(tg.get_default_classes(),
- horizon_tabs.base.CSS_TAB_GROUP_CLASSES)
- # Test get_tab
- self.assertEqual(tg.get_tab("tab_one").slug, "tab_one")
-
- # Test selected is None w/o GET input
- self.assertEqual(tg.selected, None)
-
- # Test get_selected_tab is None w/o GET input
- self.assertEqual(tg.get_selected_tab(), None)
-
- def test_tab_group_active_tab(self):
- tg = Group(self.request)
-
- # active tab w/o selected
- self.assertEqual(tg.active, tg.get_tabs()[0])
-
- # active tab w/ selected
- self.request.GET['tab'] = "tab_group__tab_delayed"
- tg = Group(self.request)
- self.assertEqual(tg.active, tg.get_tab('tab_delayed'))
-
- # active tab w/ invalid selected
- self.request.GET['tab'] = "tab_group__tab_invalid"
- tg = Group(self.request)
- self.assertEqual(tg.active, tg.get_tabs()[0])
-
- # active tab w/ disallowed selected
- self.request.GET['tab'] = "tab_group__tab_disallowed"
- tg = Group(self.request)
- self.assertEqual(tg.active, tg.get_tabs()[0])
-
- # active tab w/ disabled selected
- self.request.GET['tab'] = "tab_group__tab_disabled"
- tg = Group(self.request)
- self.assertEqual(tg.active, tg.get_tabs()[0])
-
- def test_tab_basics(self):
- tg = Group(self.request)
- tab_one = tg.get_tab("tab_one")
- tab_delayed = tg.get_tab("tab_delayed")
- tab_disabled = tg.get_tab("tab_disabled", allow_disabled=True)
-
- # Disallowed tab isn't even returned
- tab_disallowed = tg.get_tab("tab_disallowed")
- self.assertEqual(tab_disallowed, None)
-
- # get_id
- self.assertEqual(tab_one.get_id(), "tab_group__tab_one")
-
- # get_default_classes
- self.assertEqual(tab_one.get_default_classes(),
- horizon_tabs.base.CSS_ACTIVE_TAB_CLASSES)
- self.assertEqual(tab_disabled.get_default_classes(),
- horizon_tabs.base.CSS_DISABLED_TAB_CLASSES)
-
- # load, allowed, enabled
- self.assertTrue(tab_one.load)
- self.assertFalse(tab_delayed.load)
- self.assertFalse(tab_disabled.load)
- self.request.GET['tab'] = tab_delayed.get_id()
- tg = Group(self.request)
- tab_delayed = tg.get_tab("tab_delayed")
- self.assertTrue(tab_delayed.load)
-
- # is_active
- self.request.GET['tab'] = ""
- tg = Group(self.request)
- tab_one = tg.get_tab("tab_one")
- tab_delayed = tg.get_tab("tab_delayed")
- self.assertTrue(tab_one.is_active())
- self.assertFalse(tab_delayed.is_active())
-
- self.request.GET['tab'] = tab_delayed.get_id()
- tg = Group(self.request)
- tab_one = tg.get_tab("tab_one")
- tab_delayed = tg.get_tab("tab_delayed")
- self.assertFalse(tab_one.is_active())
- self.assertTrue(tab_delayed.is_active())
-
- def test_rendering(self):
- tg = Group(self.request)
- tab_one = tg.get_tab("tab_one")
- tab_delayed = tg.get_tab("tab_delayed")
- tab_disabled = tg.get_tab("tab_disabled", allow_disabled=True)
-
- # tab group
- output = tg.render()
- res = http.HttpResponse(output.strip())
- self.assertContains(res, "<li", 3)
-
- # stickiness
- self.assertContains(res, 'data-sticky-tabs="sticky"', 1)
-
- # tab
- output = tab_one.render()
- self.assertEqual(output.strip(), tab_one.name)
-
- # disabled tab
- output = tab_disabled.render()
- self.assertEqual(output.strip(), "")
-
- # preload false
- output = tab_delayed.render()
- self.assertEqual(output.strip(), "")
-
- # preload false w/ active
- self.request.GET['tab'] = tab_delayed.get_id()
- tg = Group(self.request)
- tab_delayed = tg.get_tab("tab_delayed")
- output = tab_delayed.render()
- self.assertEqual(output.strip(), tab_delayed.name)
-
- def test_table_tabs(self):
- tab_group = TableTabGroup(self.request)
- tabs = tab_group.get_tabs()
- # Only one tab, as expected.
- self.assertEqual(len(tabs), 1)
- tab = tabs[0]
- # Make sure it's the tab we think it is.
- self.assertTrue(isinstance(tab, horizon_tabs.TableTab))
- # Data should not be loaded yet.
- self.assertFalse(tab._table_data_loaded)
- table = tab._tables[MyTable.Meta.name]
- self.assertTrue(isinstance(table, MyTable))
- # Let's make sure the data *really* isn't loaded yet.
- self.assertEqual(table.data, None)
- # Okay, load the data.
- tab.load_table_data()
- self.assertTrue(tab._table_data_loaded)
- self.assertQuerysetEqual(table.data, ['<FakeObject: object_1>',
- '<FakeObject: object_2>',
- '<FakeObject: object_3>'])
- context = tab.get_context_data(self.request)
- # Make sure our table is loaded into the context correctly
- self.assertEqual(context['my_table_table'], table)
- # Since we only had one table we should get the shortcut name too.
- self.assertEqual(context['table'], table)
-
- def test_tabbed_table_view(self):
- view = TabWithTableView.as_view()
-
- # Be sure we get back a rendered table containing data for a GET
- req = self.factory.get("/")
- res = view(req)
- self.assertContains(res, "<table", 1)
- self.assertContains(res, "Displaying 3 items", 1)
-
- # AJAX response to GET for row update
- params = {"table": "my_table", "action": "row_update", "obj_id": "1"}
- req = self.factory.get('/', params,
- HTTP_X_REQUESTED_WITH='XMLHttpRequest')
- res = view(req)
- self.assertEqual(res.status_code, 200)
- # Make sure we got back a row but not a table or body
- self.assertContains(res, "<tr", 1)
- self.assertContains(res, "<table", 0)
- self.assertContains(res, "<body", 0)
-
- # Response to POST for table action
- action_string = "my_table__toggle__2"
- req = self.factory.post('/', {'action': action_string})
- res = view(req)
- self.assertEqual(res.status_code, 302)
- self.assertEqual(res["location"], "/")
-
- # Ensure that lookup errors are raised as such instead of converted
- # to TemplateSyntaxErrors.
- action_string = "my_table__toggle__2000000000"
- req = self.factory.post('/', {'action': action_string})
- self.assertRaises(exceptions.Http302, view, req)
-
-
-class TabExceptionTests(test.TestCase):
- def setUp(self):
- super(TabExceptionTests, self).setUp()
- self._original_tabs = copy.copy(TabWithTableView.tab_group_class.tabs)
- TabWithTableView.tab_group_class.tabs.append(RecoverableErrorTab)
-
- def tearDown(self):
- super(TabExceptionTests, self).tearDown()
- TabWithTableView.tab_group_class.tabs = self._original_tabs
-
- def test_tab_view_exception(self):
- view = TabWithTableView.as_view()
- req = self.factory.get("/")
- res = view(req)
- self.assertMessageCount(res, error=1)
diff --git a/horizon/test/tests/templatetags.py b/horizon/test/tests/templatetags.py
deleted file mode 100644
index 2c772c26..00000000
--- a/horizon/test/tests/templatetags.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import re
-
-from django.conf import settings
-from django.template import Context
-from django.template import Template
-from django.utils.text import normalize_newlines
-
-from horizon.test import helpers as test
-
-
-def single_line(text):
- ''' Quick utility to make comparing template output easier. '''
- return re.sub(' +',
- ' ',
- normalize_newlines(text).replace('\n', '')).strip()
-
-
-class TemplateTagTests(test.TestCase):
- '''Test Custom Template Tag'''
- def render_template_tag(self, tag_name, tag_require=''):
- '''Render a Custom Template Tag to string'''
- template = Template("{%% load %s %%}{%% %s %%}"
- % (tag_require, tag_name))
- return template.render(Context())
-
- def test_site_branding_tag(self):
- '''Test if site_branding tag renders the correct setting'''
- rendered_str = self.render_template_tag("site_branding", "branding")
- self.assertEqual(settings.SITE_BRANDING, rendered_str.strip(),
- "tag site_branding renders %s" % rendered_str.strip())
diff --git a/horizon/test/tests/utils.py b/horizon/test/tests/utils.py
deleted file mode 100644
index bf7146a4..00000000
--- a/horizon/test/tests/utils.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-import os
-
-from django.core.exceptions import ValidationError
-
-from horizon.test import helpers as test
-from horizon.utils import fields
-from horizon.utils import secret_key
-
-
-class ValidatorsTests(test.TestCase):
- def test_validate_ipv4_cidr(self):
- GOOD_CIDRS = ("192.168.1.1/16",
- "192.0.0.1/17",
- "0.0.0.0/16",
- "10.144.11.107/4",
- "255.255.255.255/0",
- "0.1.2.3/16",
- "0.0.0.0/32",
- # short form
- "128.0/16",
- "128/4")
- BAD_CIDRS = ("255.255.255.256\\",
- "256.255.255.255$",
- "1.2.3.4.5/41",
- "0.0.0.0/99",
- "127.0.0.1/",
- "127.0.0.1/33",
- "127.0.0.1/-1",
- "127.0.0.1/100",
- # some valid IPv6 addresses
- "fe80::204:61ff:254.157.241.86/4",
- "fe80::204:61ff:254.157.241.86/0",
- "2001:0DB8::CD30:0:0:0:0/60",
- "2001:0DB8::CD30:0/90")
- ip = fields.IPField(mask=True, version=fields.IPv4)
- for cidr in GOOD_CIDRS:
- self.assertIsNone(ip.validate(cidr))
- for cidr in BAD_CIDRS:
- self.assertRaises(ValidationError, ip.validate, cidr)
-
- def test_validate_ipv6_cidr(self):
- GOOD_CIDRS = ("::ffff:0:0/56",
- "2001:0db8::1428:57ab/17",
- "FEC0::/10",
- "fe80::204:61ff:254.157.241.86/4",
- "fe80::204:61ff:254.157.241.86/0",
- "2001:0DB8::CD30:0:0:0:0/60",
- "2001:0DB8::CD30:0/90",
- "::1/128")
- BAD_CIDRS = ("1111:2222:3333:4444:::/",
- "::2222:3333:4444:5555:6666:7777:8888:\\",
- ":1111:2222:3333:4444::6666:1.2.3.4/1000",
- "1111:2222::4444:5555:6666::8888@",
- "1111:2222::4444:5555:6666:8888/",
- "::ffff:0:0/129",
- "1.2.3.4:1111:2222::5555//22",
- "fe80::204:61ff:254.157.241.86/200",
- # some valid IPv4 addresses
- "10.144.11.107/4",
- "255.255.255.255/0",
- "0.1.2.3/16")
- ip = fields.IPField(mask=True, version=fields.IPv6)
- for cidr in GOOD_CIDRS:
- self.assertIsNone(ip.validate(cidr))
- for cidr in BAD_CIDRS:
- self.assertRaises(ValidationError, ip.validate, cidr)
-
- def test_validate_mixed_cidr(self):
- GOOD_CIDRS = ("::ffff:0:0/56",
- "2001:0db8::1428:57ab/17",
- "FEC0::/10",
- "fe80::204:61ff:254.157.241.86/4",
- "fe80::204:61ff:254.157.241.86/0",
- "2001:0DB8::CD30:0:0:0:0/60",
- "0.0.0.0/16",
- "10.144.11.107/4",
- "255.255.255.255/0",
- "0.1.2.3/16",
- # short form
- "128.0/16",
- "10/4")
- BAD_CIDRS = ("1111:2222:3333:4444::://",
- "::2222:3333:4444:5555:6666:7777:8888:",
- ":1111:2222:3333:4444::6666:1.2.3.4/1/1",
- "1111:2222::4444:5555:6666::8888\\2",
- "1111:2222::4444:5555:6666:8888/",
- "1111:2222::4444:5555:6666::8888/130",
- "127.0.0.1/",
- "127.0.0.1/33",
- "127.0.0.1/-1")
- ip = fields.IPField(mask=True, version=fields.IPv4 | fields.IPv6)
- for cidr in GOOD_CIDRS:
- self.assertIsNone(ip.validate(cidr))
- for cidr in BAD_CIDRS:
- self.assertRaises(ValidationError, ip.validate, cidr)
-
- def test_validate_IPs(self):
- GOOD_IPS_V4 = ("0.0.0.0",
- "10.144.11.107",
- "169.144.11.107",
- "172.100.11.107",
- "255.255.255.255",
- "0.1.2.3")
- GOOD_IPS_V6 = ("",
- "::ffff:0:0",
- "2001:0db8::1428:57ab",
- "FEC0::",
- "fe80::204:61ff:254.157.241.86",
- "fe80::204:61ff:254.157.241.86",
- "2001:0DB8::CD30:0:0:0:0")
- BAD_IPS_V4 = ("1111:2222:3333:4444:::",
- "::2222:3333:4444:5555:6666:7777:8888:",
- ":1111:2222:3333:4444::6666:1.2.3.4",
- "1111:2222::4444:5555:6666::8888",
- "1111:2222::4444:5555:6666:8888/",
- "1111:2222::4444:5555:6666::8888/130",
- "127.0.0.1/",
- "127.0.0.1/33",
- "127.0.0.1/-1")
- BAD_IPS_V6 = ("1111:2222:3333:4444:::",
- "::2222:3333:4444:5555:6666:7777:8888:",
- ":1111:2222:3333:4444::6666:1.2.3.4",
- "1111:2222::4444:5555:6666::8888",
- "1111:2222::4444:5555:6666:8888/",
- "1111:2222::4444:5555:6666::8888/130")
- ipv4 = fields.IPField(required=True, version=fields.IPv4)
- ipv6 = fields.IPField(required=False, version=fields.IPv6)
- ipmixed = fields.IPField(required=False,
- version=fields.IPv4 | fields.IPv6)
-
- for ip_addr in GOOD_IPS_V4:
- self.assertIsNone(ipv4.validate(ip_addr))
- self.assertIsNone(ipmixed.validate(ip_addr))
-
- for ip_addr in GOOD_IPS_V6:
- self.assertIsNone(ipv6.validate(ip_addr))
- self.assertIsNone(ipmixed.validate(ip_addr))
-
- for ip_addr in BAD_IPS_V4:
- self.assertRaises(ValidationError, ipv4.validate, ip_addr)
- self.assertRaises(ValidationError, ipmixed.validate, ip_addr)
-
- for ip_addr in BAD_IPS_V6:
- self.assertRaises(ValidationError, ipv6.validate, ip_addr)
- self.assertRaises(ValidationError, ipmixed.validate, ip_addr)
-
- self.assertRaises(ValidationError, ipv4.validate, "") # required=True
-
- iprange = fields.IPField(required=False,
- mask=True,
- mask_range_from=10,
- version=fields.IPv4 | fields.IPv6)
- self.assertRaises(ValidationError, iprange.validate,
- "fe80::204:61ff:254.157.241.86/6")
- self.assertRaises(ValidationError, iprange.validate,
- "169.144.11.107/8")
- self.assertIsNone(iprange.validate("fe80::204:61ff:254.157.241.86/36"))
- self.assertIsNone(iprange.validate("169.144.11.107/18"))
-
-
-class SecretKeyTests(test.TestCase):
- def test_generate_secret_key(self):
- key = secret_key.generate_key(32)
- self.assertEqual(len(key), 32)
- self.assertNotEqual(key, secret_key.generate_key(32))
-
- def test_generate_or_read_key_from_file(self):
- key_file = ".test_secret_key_store"
- key = secret_key.generate_or_read_from_file(key_file)
-
- # Consecutive reads should come from the already existing file:
- self.assertEqual(key, secret_key.generate_or_read_from_file(key_file))
-
- # Key file only be read/writable by user:
- self.assertEqual(oct(os.stat(key_file).st_mode & 0777), "0600")
- os.chmod(key_file, 0777)
- self.assertRaises(secret_key.FilePermissionError,
- secret_key.generate_or_read_from_file, key_file)
- os.remove(key_file)
diff --git a/horizon/test/tests/workflows.py b/horizon/test/tests/workflows.py
deleted file mode 100644
index 00522842..00000000
--- a/horizon/test/tests/workflows.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django import forms
-from django import http
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon.test import helpers as test
-from horizon import workflows
-
-
-PROJECT_ID = "a23lkjre389fwenj"
-INSTANCE_ID = "sdlkjhf9832roiw"
-
-
-def local_callback_func(request, context):
- return "one"
-
-
-def other_callback_func(request, context):
- return "two"
-
-
-def extra_callback_func(request, context):
- return "extra"
-
-
-class TestActionOne(workflows.Action):
- project_id = forms.ChoiceField(label=_("Project"))
- user_id = forms.ChoiceField(label=_("User"))
-
- class Meta:
- name = _("Test Action One")
- slug = "test_action_one"
-
- def populate_project_id_choices(self, request, context):
- return [(PROJECT_ID, "test_project")]
-
- def populate_user_id_choices(self, request, context):
- return [(request.user.id, request.user.username)]
-
- def handle(self, request, context):
- return {"foo": "bar"}
-
-
-class TestActionTwo(workflows.Action):
- instance_id = forms.CharField(label=_("Instance"))
-
- class Meta:
- name = _("Test Action Two")
- slug = "test_action_two"
-
-
-class TestActionThree(workflows.Action):
- extra = forms.CharField(widget=forms.widgets.Textarea)
-
- class Meta:
- name = _("Test Action Three")
- slug = "test_action_three"
-
-
-class AdminAction(workflows.Action):
- admin_id = forms.CharField(label=_("Admin"))
-
- class Meta:
- name = _("Admin Action")
- slug = "admin_action"
- permissions = ("horizon.test",)
-
-
-class TestStepOne(workflows.Step):
- action_class = TestActionOne
- contributes = ("project_id", "user_id")
-
-
-class TestStepTwo(workflows.Step):
- action_class = TestActionTwo
- depends_on = ("project_id",)
- contributes = ("instance_id",)
- connections = {"project_id": (local_callback_func,
- "horizon.test.tests.workflows.other_callback_func")}
-
-
-class TestExtraStep(workflows.Step):
- action_class = TestActionThree
- depends_on = ("project_id",)
- contributes = ("extra_data",)
- connections = {"project_id": (extra_callback_func,)}
- after = TestStepOne
- before = TestStepTwo
-
-
-class AdminStep(workflows.Step):
- action_class = AdminAction
- contributes = ("admin_id",)
- after = TestStepOne
- before = TestStepTwo
-
-
-class TestWorkflow(workflows.Workflow):
- slug = "test_workflow"
- default_steps = (TestStepOne, TestStepTwo)
-
-
-class TestWorkflowView(workflows.WorkflowView):
- workflow_class = TestWorkflow
- template_name = "workflow.html"
-
-
-class WorkflowsTests(test.TestCase):
- def setUp(self):
- super(WorkflowsTests, self).setUp()
-
- def tearDown(self):
- super(WorkflowsTests, self).tearDown()
- self._reset_workflow()
-
- def _reset_workflow(self):
- TestWorkflow._cls_registry = set([])
-
- def test_workflow_construction(self):
- TestWorkflow.register(TestExtraStep)
- flow = TestWorkflow(self.request)
- self.assertQuerysetEqual(flow.steps,
- ['<TestStepOne: test_action_one>',
- '<TestExtraStep: test_action_three>',
- '<TestStepTwo: test_action_two>'])
- self.assertEqual(flow.depends_on, set(['project_id']))
-
- def test_step_construction(self):
- step_one = TestStepOne(TestWorkflow(self.request))
- # Action slug is moved from Meta by metaclass, and
- # Step inherits slug from action.
- self.assertEqual(step_one.name, TestActionOne.name)
- self.assertEqual(step_one.slug, TestActionOne.slug)
- # Handlers should be empty since there are no connections.
- self.assertEqual(step_one._handlers, {})
-
- step_two = TestStepTwo(TestWorkflow(self.request))
- # Handlers should be populated since we do have connections.
- self.assertEqual(step_two._handlers["project_id"],
- [local_callback_func, other_callback_func])
-
- def test_step_invalid_callback(self):
- # This should raise an exception
- class InvalidStep(TestStepTwo):
- connections = {"project_id": ('local_callback_func',)}
-
- with self.assertRaises(ValueError):
- InvalidStep(TestWorkflow(self.request))
-
- def test_connection_handlers_called(self):
- TestWorkflow.register(TestExtraStep)
- flow = TestWorkflow(self.request)
-
- # This should set the value without any errors, but trigger nothing
- flow.context['does_not_exist'] = False
- self.assertEqual(flow.context['does_not_exist'], False)
-
- # The order here is relevant. Note that we inserted "extra" between
- # steps one and two, and one has no handlers, so we should see
- # a response from extra, then one from each of step two's handlers.
- val = flow.context.set('project_id', PROJECT_ID)
- self.assertEqual(val, [('test_action_three', 'extra'),
- ('test_action_two', 'one'),
- ('test_action_two', 'two')])
-
- def test_workflow_validation(self):
- flow = TestWorkflow(self.request)
-
- # Missing items fail validation.
- with self.assertRaises(exceptions.WorkflowValidationError):
- flow.is_valid()
-
- # All required items pass validation.
- seed = {"project_id": PROJECT_ID,
- "user_id": self.user.id,
- "instance_id": INSTANCE_ID}
- req = self.factory.post("/", seed)
- req.user = self.user
- flow = TestWorkflow(req, context_seed={"project_id": PROJECT_ID})
- for step in flow.steps:
- if not step.action.is_valid():
- self.fail("Step %s was unexpectedly invalid: %s"
- % (step.slug, step.action.errors))
- self.assertTrue(flow.is_valid())
-
- # Additional items shouldn't affect validation
- flow.context.set("extra_data", "foo")
- self.assertTrue(flow.is_valid())
-
- def test_workflow_finalization(self):
- flow = TestWorkflow(self.request)
- self.assertTrue(flow.finalize())
-
- def test_workflow_view(self):
- view = TestWorkflowView.as_view()
- req = self.factory.get("/")
- res = view(req)
- self.assertEqual(res.status_code, 200)
-
- def test_workflow_registration(self):
- req = self.factory.get("/foo")
- flow = TestWorkflow(req)
- self.assertQuerysetEqual(flow.steps,
- ['<TestStepOne: test_action_one>',
- '<TestStepTwo: test_action_two>'])
-
- TestWorkflow.register(TestExtraStep)
- flow = TestWorkflow(req)
- self.assertQuerysetEqual(flow.steps,
- ['<TestStepOne: test_action_one>',
- '<TestExtraStep: test_action_three>',
- '<TestStepTwo: test_action_two>'])
-
- def test_workflow_render(self):
- TestWorkflow.register(TestExtraStep)
- req = self.factory.get("/foo")
- flow = TestWorkflow(req)
- output = http.HttpResponse(flow.render())
- self.assertContains(output, unicode(flow.name))
- self.assertContains(output, unicode(TestActionOne.name))
- self.assertContains(output, unicode(TestActionTwo.name))
- self.assertContains(output, unicode(TestActionThree.name))
-
- def test_has_permissions(self):
- self.assertQuerysetEqual(TestWorkflow._cls_registry, [])
- TestWorkflow.register(AdminStep)
- flow = TestWorkflow(self.request)
- step = AdminStep(flow)
-
- self.assertItemsEqual(step.permissions,
- ("horizon.test",))
- self.assertQuerysetEqual(flow.steps,
- ['<TestStepOne: test_action_one>',
- '<TestStepTwo: test_action_two>'])
-
- self.set_permissions(['test'])
- self.request.user = self.user
- flow = TestWorkflow(self.request)
- self.assertQuerysetEqual(flow.steps,
- ['<TestStepOne: test_action_one>',
- '<AdminStep: admin_action>',
- '<TestStepTwo: test_action_two>'])
-
- def test_entry_point(self):
- req = self.factory.get("/foo")
- flow = TestWorkflow(req)
- self.assertEqual(flow.get_entry_point(), "test_action_one")
-
- flow = TestWorkflow(req, entry_point="test_action_two")
- self.assertEqual(flow.get_entry_point(), "test_action_two")
diff --git a/horizon/test/urls.py b/horizon/test/urls.py
deleted file mode 100644
index 4fd0957b..00000000
--- a/horizon/test/urls.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-URL patterns for testing Horizon views.
-"""
-
-from django.conf.urls.defaults import include
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-from django.contrib.staticfiles.urls import staticfiles_urlpatterns
-from django.views.generic import TemplateView
-
-import horizon
-
-
-urlpatterns = patterns('',
- url(r'', include(horizon.urls)),
- url(r"auth/login/", "django.contrib.auth.views.login",
- {'template_name': "auth/login.html"},
- name='login'),
- url(r'auth/', include('django.contrib.auth.urls')),
- url(r'^qunit/$',
- TemplateView.as_view(template_name="horizon/qunit.html"),
- name='qunit_tests')
-)
-
-urlpatterns += staticfiles_urlpatterns()
diff --git a/horizon/utils/__init__.py b/horizon/utils/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/horizon/utils/__init__.py
+++ /dev/null
diff --git a/horizon/utils/fields.py b/horizon/utils/fields.py
deleted file mode 100644
index 7522b3b1..00000000
--- a/horizon/utils/fields.py
+++ /dev/null
@@ -1,130 +0,0 @@
-from django.core.exceptions import ValidationError
-from django.forms import forms
-from django.forms import widgets
-from django.utils.encoding import force_unicode
-from django.utils.functional import Promise
-from django.utils.html import conditional_escape
-from django.utils.html import escape
-from django.utils.translation import ugettext_lazy as _
-import netaddr
-import re
-
-ip_allowed_symbols_re = re.compile(r'^[a-fA-F0-9:/\.]+$')
-IPv4 = 1
-IPv6 = 2
-
-
-class IPField(forms.Field):
- """
- Form field for entering IP/range values, with validation.
- Supports IPv4/IPv6 in the format:
- .. xxx.xxx.xxx.xxx
- .. xxx.xxx.xxx.xxx/zz
- .. ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
- .. ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/zz
- and all compressed forms. Also the short forms
- are supported:
- xxx/yy
- xxx.xxx/yy
-
- .. attribute:: version
-
- Specifies which IP version to validate,
- valid values are 1 (fields.IPv4), 2 (fields.IPv6) or
- both - 3 (fields.IPv4 | fields.IPv6).
- Defaults to IPv4 (1)
-
- .. attribute:: mask
-
- Boolean flag to validate subnet masks along with IP address.
- E.g: 10.0.0.1/32
-
- .. attribute:: mask_range_from
- Subnet range limitation, e.g. 16
- That means the input mask will be checked to be in the range
- 16:max_value. Useful to limit the subnet ranges
- to A/B/C-class networks.
- """
- invalid_format_message = _("Incorrect format for IP address")
- invalid_version_message = _("Invalid version for IP address")
- invalid_mask_message = _("Invalid subnet mask")
- max_v4_mask = 32
- max_v6_mask = 128
-
- def __init__(self, *args, **kwargs):
- self.mask = kwargs.pop("mask", None)
- self.min_mask = kwargs.pop("mask_range_from", 0)
- self.version = kwargs.pop('version', IPv4)
-
- super(IPField, self).__init__(*args, **kwargs)
-
- def validate(self, value):
- super(IPField, self).validate(value)
- if not value and not self.required:
- return
-
- try:
- if self.mask:
- self.ip = netaddr.IPNetwork(value)
- else:
- self.ip = netaddr.IPAddress(value)
- except:
- raise ValidationError(self.invalid_format_message)
-
- if not any([self.version & IPv4 > 0 and self.ip.version == 4,
- self.version & IPv6 > 0 and self.ip.version == 6]):
- raise ValidationError(self.invalid_version_message)
-
- if self.mask:
- if self.ip.version == 4 and \
- not self.min_mask <= self.ip.prefixlen <= self.max_v4_mask:
- raise ValidationError(self.invalid_mask_message)
-
- if self.ip.version == 6 and \
- not self.min_mask <= self.ip.prefixlen <= self.max_v6_mask:
- raise ValidationError(self.invalid_mask_message)
-
- def clean(self, value):
- super(IPField, self).clean(value)
- return str(getattr(self, "ip", ""))
-
-
-class SelectWidget(widgets.Select):
- """
- Customizable select widget, that allows to render
- data-xxx attributes from choices.
-
- .. attribute:: data_attrs
-
- Specifies object properties to serialize as
- data-xxx attribute. If passed ('id', ),
- this will be rendered as:
- <option data-id="123">option_value</option>
- where 123 is the value of choice_value.id
-
- .. attribute:: transform
-
- A callable used to render the display value
- from the option object.
- """
- def __init__(self, attrs=None, choices=(), data_attrs=(), transform=None):
- self.data_attrs = data_attrs
- self.transform = transform
- super(SelectWidget, self).__init__(attrs, choices)
-
- def render_option(self, selected_choices, option_value, option_label):
- option_value = force_unicode(option_value)
- other_html = (option_value in selected_choices) and \
- u' selected="selected"' or ''
- if not isinstance(option_label, (basestring, Promise)):
- for data_attr in self.data_attrs:
- data_value = conditional_escape(
- force_unicode(getattr(option_label,
- data_attr, "")))
- other_html += ' data-%s="%s"' % (data_attr, data_value)
-
- if self.transform:
- option_label = self.transform(option_label)
- return u'<option value="%s"%s>%s</option>' % (
- escape(option_value), other_html,
- conditional_escape(force_unicode(option_label)))
diff --git a/horizon/utils/filters.py b/horizon/utils/filters.py
deleted file mode 100644
index b47a0cf3..00000000
--- a/horizon/utils/filters.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import iso8601
-
-from django.template.defaultfilters import register
-
-
-@register.filter
-def replace_underscores(string):
- return string.replace("_", " ")
-
-
-@register.filter
-def parse_isotime(timestr):
- """
- This duplicates oslo timeutils parse_isotime but with a
- @register.filter annotation.
- """
- try:
- return iso8601.parse_date(timestr)
- except iso8601.ParseError as e:
- raise ValueError(e.message)
- except TypeError as e:
- raise ValueError(e.message)
diff --git a/horizon/utils/functions.py b/horizon/utils/functions.py
deleted file mode 100644
index e7ae8d46..00000000
--- a/horizon/utils/functions.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import math
-
-from django.utils.encoding import force_unicode
-from django.utils.functional import lazy
-
-
-def _lazy_join(separator, strings):
- return separator.join([force_unicode(s)
- for s in strings])
-
-lazy_join = lazy(_lazy_join, unicode)
-
-
-def bytes_to_gigabytes(bytes):
- # Converts the number of bytes to the next highest number of Gigabytes
- # For example 5000000 (5 Meg) would return '1'
- return int(math.ceil(float(bytes) / 1024 ** 3))
diff --git a/horizon/utils/html.py b/horizon/utils/html.py
deleted file mode 100644
index a3bb3f8c..00000000
--- a/horizon/utils/html.py
+++ /dev/null
@@ -1,56 +0,0 @@
-import copy
-
-from django.forms.util import flatatt
-
-
-class HTMLElement(object):
- """ A generic base class that gracefully handles html-style attributes. """
- def __init__(self):
- self.attrs = getattr(self, "attrs", {})
- self.classes = getattr(self, "classes", [])
-
- def get_default_classes(self):
- """
- Returns an iterable of default classes which should be combined with
- any other declared classes.
- """
- return []
-
- def get_default_attrs(self):
- """
- Returns a dict of default attributes which should be combined with
- other declared attributes.
- """
- return {}
-
- def get_final_attrs(self):
- """
- Returns a dict containing the final attributes of this element
- which will be rendered.
- """
- final_attrs = copy.copy(self.get_default_attrs())
- final_attrs.update(self.attrs)
- # Handle css class concatenation
- default = " ".join(self.get_default_classes())
- defined = self.attrs.get('class', '')
- additional = " ".join(getattr(self, "classes", []))
- non_empty = [test for test in (defined, default, additional) if test]
- final_classes = " ".join(non_empty).strip()
- final_attrs.update({'class': final_classes})
- return final_attrs
-
- @property
- def attr_string(self):
- """
- Returns a flattened string of HTML attributes based on the
- ``attrs`` dict provided to the class.
- """
- return flatatt(self.get_final_attrs())
-
- @property
- def class_string(self):
- """
- Returns a list of class name of HTML Element in string
- """
- classes_str = " ".join(self.classes)
- return classes_str
diff --git a/horizon/utils/memoized.py b/horizon/utils/memoized.py
deleted file mode 100644
index 6c954b55..00000000
--- a/horizon/utils/memoized.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import functools
-
-
-class memoized(object):
- '''Decorator. Caches a function's return value each time it is called.
- If called later with the same arguments, the cached value is returned
- (not reevaluated).
- '''
- def __init__(self, func):
- self.func = func
- self.cache = {}
-
- def __call__(self, *args):
- try:
- return self.cache[args]
- except KeyError:
- value = self.func(*args)
- self.cache[args] = value
- return value
- except TypeError:
- # uncachable -- for instance, passing a list as an argument.
- # Better to not cache than to blow up entirely.
- return self.func(*args)
-
- def __repr__(self):
- '''Return the function's docstring.'''
- return self.func.__doc__ or ''
-
- def __get__(self, obj, objtype):
- '''Support instance methods.'''
- return functools.partial(self.__call__, obj)
-
- def __str__(self):
- return str(self.func)
diff --git a/horizon/utils/secret_key.py b/horizon/utils/secret_key.py
deleted file mode 100644
index 6df5533f..00000000
--- a/horizon/utils/secret_key.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-from __future__ import with_statement # Python 2.5 compliance
-
-import lockfile
-import os
-import random
-import string
-
-
-class FilePermissionError(Exception):
- """The key file permissions are insecure."""
- pass
-
-
-def generate_key(key_length=64):
- """Secret key generator.
-
- The quality of randomness depends on operating system support,
- see http://docs.python.org/library/random.html#random.SystemRandom.
- """
- if hasattr(random, 'SystemRandom'):
- choice = random.SystemRandom().choice
- else:
- choice = random.choice
- return ''.join(map(lambda x: choice(string.digits + string.letters),
- range(key_length)))
-
-
-def generate_or_read_from_file(key_file='.secret_key', key_length=64):
- """Multiprocess-safe secret key file generator.
-
- Useful to replace the default (and thus unsafe) SECRET_KEY in settings.py
- upon first start. Save to use, i.e. when multiple Python interpreters
- serve the dashboard Django application (e.g. in a mod_wsgi + daemonized
- environment). Also checks if file permissions are set correctly and
- throws an exception if not.
- """
- lock = lockfile.FileLock(key_file)
- with lock:
- if not os.path.exists(key_file):
- key = generate_key(key_length)
- old_umask = os.umask(0177) # Use '0600' file permissions
- with open(key_file, 'w') as f:
- f.write(key)
- os.umask(old_umask)
- else:
- if oct(os.stat(key_file).st_mode & 0777) != '0600':
- raise FilePermissionError("Insecure key file permissions!")
- with open(key_file, 'r') as f:
- key = f.readline()
- return key
diff --git a/horizon/utils/validators.py b/horizon/utils/validators.py
deleted file mode 100644
index 183e5a41..00000000
--- a/horizon/utils/validators.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.exceptions import ValidationError
-
-from horizon import conf
-
-
-def validate_port_range(port):
- if port not in range(-1, 65536):
- raise ValidationError("Not a valid port number")
-
-
-def validate_ip_protocol(ip_proto):
- if ip_proto not in range(-1, 256):
- raise ValidationError("%s is not a valid ip protocol number" %
- type(ip_proto))
-
-
-def password_validator():
- return conf.HORIZON_CONFIG["password_validator"]["regex"]
-
-
-def password_validator_msg():
- return conf.HORIZON_CONFIG["password_validator"]["help_text"]
diff --git a/horizon/version.py b/horizon/version.py
deleted file mode 100644
index 6280a758..00000000
--- a/horizon/version.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 OpenStack LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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_info = pbr.version.VersionInfo('horizon')
diff --git a/horizon/views.py b/horizon/views.py
deleted file mode 100644
index 548fbf15..00000000
--- a/horizon/views.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django import shortcuts
-from django.views import generic
-
-import horizon
-from horizon import exceptions
-
-
-def user_home(request):
- """ Reversible named view to direct a user to the appropriate homepage. """
- return shortcuts.redirect(horizon.get_user_home(request.user))
-
-
-class APIView(generic.TemplateView):
- """ A quick class-based view for putting API data into a template.
-
- Subclasses must define one method, ``get_data``, and a template name
- via the ``template_name`` attribute on the class.
-
- Errors within the ``get_data`` function are automatically caught by
- the :func:`horizon.exceptions.handle` error handler if not otherwise
- caught.
- """
- def get_data(self, request, context, *args, **kwargs):
- """
- This method should handle any necessary API calls, update the
- context object, and return the context object at the end.
- """
- raise NotImplementedError("You must define a get_data method "
- "on %s" % self.__class__.__name__)
-
- def get(self, request, *args, **kwargs):
- context = self.get_context_data(**kwargs)
- try:
- context = self.get_data(request, context, *args, **kwargs)
- except:
- exceptions.handle(request)
- return self.render_to_response(context)
diff --git a/horizon/workflows/__init__.py b/horizon/workflows/__init__.py
deleted file mode 100644
index cb4a916f..00000000
--- a/horizon/workflows/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from horizon.workflows.base import Action
-from horizon.workflows.base import Step
-from horizon.workflows.base import TableStep
-from horizon.workflows.base import UpdateMembersStep
-from horizon.workflows.base import Workflow
-from horizon.workflows.views import WorkflowView
-
-assert Action
-assert Step
-assert TableStep
-assert UpdateMembersStep
-assert Workflow
-assert WorkflowView
diff --git a/horizon/workflows/base.py b/horizon/workflows/base.py
deleted file mode 100644
index 60d8a1e9..00000000
--- a/horizon/workflows/base.py
+++ /dev/null
@@ -1,934 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import copy
-import inspect
-import logging
-
-from django.core import urlresolvers
-from django import forms
-from django.forms.forms import NON_FIELD_ERRORS
-from django import template
-from django.template.defaultfilters import linebreaks
-from django.template.defaultfilters import safe
-from django.template.defaultfilters import slugify
-from django.utils.encoding import force_unicode
-from django.utils.importlib import import_module
-from django.utils.translation import ugettext_lazy as _
-
-# FIXME: TableStep
-from django.utils.datastructures import SortedDict
-
-from horizon import base
-from horizon import exceptions
-from horizon.templatetags.horizon import has_permissions
-from horizon.utils import html
-
-
-LOG = logging.getLogger(__name__)
-
-
-class WorkflowContext(dict):
- def __init__(self, workflow, *args, **kwargs):
- super(WorkflowContext, self).__init__(*args, **kwargs)
- self._workflow = workflow
-
- def __setitem__(self, key, val):
- super(WorkflowContext, self).__setitem__(key, val)
- return self._workflow._trigger_handlers(key)
-
- def __delitem__(self, key):
- return self.__setitem__(key, None)
-
- def set(self, key, val):
- return self.__setitem__(key, val)
-
- def unset(self, key):
- return self.__delitem__(key)
-
-
-class ActionMetaclass(forms.forms.DeclarativeFieldsMetaclass):
- def __new__(mcs, name, bases, attrs):
- # Pop Meta for later processing
- opts = attrs.pop("Meta", None)
- # Create our new class
- cls = super(ActionMetaclass, mcs).__new__(mcs, name, bases, attrs)
- # Process options from Meta
- cls.name = getattr(opts, "name", name)
- cls.slug = getattr(opts, "slug", slugify(name))
- cls.permissions = getattr(opts, "permissions", ())
- cls.progress_message = getattr(opts,
- "progress_message",
- _("Processing..."))
- cls.help_text = getattr(opts, "help_text", "")
- cls.help_text_template = getattr(opts, "help_text_template", None)
- return cls
-
-
-class Action(forms.Form):
- """
- An ``Action`` represents an atomic logical interaction you can have with
- the system. This is easier to understand with a conceptual example: in the
- context of a "launch instance" workflow, actions would include "naming
- the instance", "selecting an image", and ultimately "launching the
- instance".
-
- Because ``Actions`` are always interactive, they always provide form
- controls, and thus inherit from Django's ``Form`` class. However, they
- have some additional intelligence added to them:
-
- * ``Actions`` are aware of the permissions required to complete them.
-
- * ``Actions`` have a meta-level concept of "help text" which is meant to be
- displayed in such a way as to give context to the action regardless of
- where the action is presented in a site or workflow.
-
- * ``Actions`` understand how to handle their inputs and produce outputs,
- much like :class:`~horizon.forms.SelfHandlingForm` does now.
-
- ``Action`` classes may define the following attributes in a ``Meta``
- class within them:
-
- .. attribute:: name
-
- The verbose name for this action. Defaults to the name of the class.
-
- .. attribute:: slug
-
- A semi-unique slug for this action. Defaults to the "slugified" name
- of the class.
-
- .. attribute:: permissions
-
- A list of permission names which this action requires in order to be
- completed. Defaults to an empty list (``[]``).
-
- .. attribute:: help_text
-
- A string of simple help text to be displayed alongside the Action's
- fields.
-
- .. attribute:: help_text_template
-
- A path to a template which contains more complex help text to be
- displayed alongside the Action's fields. In conjunction with
- :meth:`~horizon.workflows.Action.get_help_text` method you can
- customize your help text template to display practically anything.
- """
-
- __metaclass__ = ActionMetaclass
-
- def __init__(self, request, context, *args, **kwargs):
- if request.method == "POST":
- super(Action, self).__init__(request.POST, initial=context)
- else:
- super(Action, self).__init__(initial=context)
-
- if not hasattr(self, "handle"):
- raise AttributeError("The action %s must define a handle method."
- % self.__class__.__name__)
- self.request = request
- self._populate_choices(request, context)
-
- def __unicode__(self):
- return force_unicode(self.name)
-
- def __repr__(self):
- return "<%s: %s>" % (self.__class__.__name__, self.slug)
-
- def _populate_choices(self, request, context):
- for field_name, bound_field in self.fields.items():
- meth = getattr(self, "populate_%s_choices" % field_name, None)
- if meth is not None and callable(meth):
- bound_field.choices = meth(request, context)
-
- def get_help_text(self, extra_context=None):
- """ Returns the help text for this step. """
- text = ""
- extra_context = extra_context or {}
- if self.help_text_template:
- tmpl = template.loader.get_template(self.help_text_template)
- context = template.RequestContext(self.request, extra_context)
- text += tmpl.render(context)
- else:
- text += linebreaks(force_unicode(self.help_text))
- return safe(text)
-
- def add_error(self, message):
- """
- Adds an error to the Action's Step based on API issues.
- """
- self._get_errors()[NON_FIELD_ERRORS] = self.error_class([message])
-
- def handle(self, request, context):
- """
- Handles any requisite processing for this action. The method should
- return either ``None`` or a dictionary of data to be passed to
- :meth:`~horizon.workflows.Step.contribute`.
-
- Returns ``None`` by default, effectively making it a no-op.
- """
- return None
-
-
-class Step(object):
- """
- A step is a wrapper around an action which defines it's context in a
- workflow. It knows about details such as:
-
- * The workflow's context data (data passed from step to step).
-
- * The data which must be present in the context to begin this step (the
- step's dependencies).
-
- * The keys which will be added to the context data upon completion of the
- step.
-
- * The connections between this step's fields and changes in the context
- data (e.g. if that piece of data changes, what needs to be updated in
- this step).
-
- A ``Step`` class has the following attributes:
-
- .. attribute:: action
-
- The :class:`~horizon.workflows.Action` class which this step wraps.
-
- .. attribute:: depends_on
-
- A list of context data keys which this step requires in order to
- begin interaction.
-
- .. attribute:: contributes
-
- A list of keys which this step will contribute to the workflow's
- context data. Optional keys should still be listed, even if their
- values may be set to ``None``.
-
- .. attribute:: connections
-
- A dictionary which maps context data key names to lists of callbacks.
- The callbacks may be functions, dotted python paths to functions
- which may be imported, or dotted strings beginning with ``"self"``
- to indicate methods on the current ``Step`` instance.
-
- .. attribute:: before
-
- Another ``Step`` class. This optional attribute is used to provide
- control over workflow ordering when steps are dynamically added to
- workflows. The workflow mechanism will attempt to place the current
- step before the step specified in the attribute.
-
- .. attribute:: after
-
- Another ``Step`` class. This attribute has the same purpose as
- :meth:`~horizon.workflows.Step.before` except that it will instead
- attempt to place the current step after the given step.
-
- .. attribute:: help_text
-
- A string of simple help text which will be prepended to the ``Action``
- class' help text if desired.
-
- .. attribute:: template_name
-
- A path to a template which will be used to render this step. In
- general the default common template should be used. Default:
- ``"horizon/common/_workflow_step.html"``.
-
- .. attribute:: has_errors
-
- A boolean value which indicates whether or not this step has any
- errors on the action within it or in the scope of the workflow. This
- attribute will only accurately reflect this status after validation
- has occurred.
-
- .. attribute:: slug
-
- Inherited from the ``Action`` class.
-
- .. attribute:: name
-
- Inherited from the ``Action`` class.
-
- .. attribute:: permissions
-
- Inherited from the ``Action`` class.
- """
- action_class = None
- depends_on = ()
- contributes = ()
- connections = None
- before = None
- after = None
- help_text = ""
- template_name = "horizon/common/_workflow_step.html"
-
- def __repr__(self):
- return "<%s: %s>" % (self.__class__.__name__, self.slug)
-
- def __unicode__(self):
- return force_unicode(self.name)
-
- def __init__(self, workflow):
- super(Step, self).__init__()
- self.workflow = workflow
-
- cls = self.__class__.__name__
- if not (self.action_class and issubclass(self.action_class, Action)):
- raise AttributeError("You must specify an action for %s." % cls)
-
- self.slug = self.action_class.slug
- self.name = self.action_class.name
- self.permissions = self.action_class.permissions
- self.has_errors = False
- self._handlers = {}
-
- if self.connections is None:
- # We want a dict, but don't want to declare a mutable type on the
- # class directly.
- self.connections = {}
-
- # Gather our connection handlers and make sure they exist.
- for key, handlers in self.connections.items():
- self._handlers[key] = []
- # TODO(gabriel): This is a poor substitute for broader handling
- if not isinstance(handlers, (list, tuple)):
- raise TypeError("The connection handlers for %s must be a "
- "list or tuple." % cls)
- for possible_handler in handlers:
- if callable(possible_handler):
- # If it's callable we know the function exists and is valid
- self._handlers[key].append(possible_handler)
- continue
- elif not isinstance(possible_handler, basestring):
- return TypeError("Connection handlers must be either "
- "callables or strings.")
- bits = possible_handler.split(".")
- if bits[0] == "self":
- root = self
- for bit in bits[1:]:
- try:
- root = getattr(root, bit)
- except AttributeError:
- raise AttributeError("The connection handler %s "
- "could not be found on %s."
- % (possible_handler, cls))
- handler = root
- elif len(bits) == 1:
- # Import by name from local module not supported
- raise ValueError("Importing a local function as a string "
- "is not supported for the connection "
- "handler %s on %s."
- % (possible_handler, cls))
- else:
- # Try a general import
- module_name = ".".join(bits[:-1])
- try:
- mod = import_module(module_name)
- handler = getattr(mod, bits[-1])
- except ImportError:
- raise ImportError("Could not import %s from the "
- "module %s as a connection "
- "handler on %s."
- % (bits[-1], module_name, cls))
- except AttributeError:
- raise AttributeError("Could not import %s from the "
- "module %s as a connection "
- "handler on %s."
- % (bits[-1], module_name, cls))
- self._handlers[key].append(handler)
-
- @property
- def action(self):
- if not getattr(self, "_action", None):
- try:
- # Hook in the action context customization.
- workflow_context = dict(self.workflow.context)
- context = self.prepare_action_context(self.workflow.request,
- workflow_context)
- self._action = self.action_class(self.workflow.request,
- context)
- except:
- LOG.exception("Problem instantiating action class.")
- raise
- return self._action
-
- def prepare_action_context(self, request, context):
- """
- Allows for customization of how the workflow context is passed to the
- action; this is the reverse of what "contribute" does to make the
- action outputs sane for the workflow. Changes to the context are not
- saved globally here. They are localized to the action.
-
- Simply returns the unaltered context by default.
- """
- return context
-
- def get_id(self):
- """ Returns the ID for this step. Suitable for use in HTML markup. """
- return "%s__%s" % (self.workflow.slug, self.slug)
-
- def _verify_contributions(self, context):
- for key in self.contributes:
- # Make sure we don't skip steps based on weird behavior of
- # POST query dicts.
- field = self.action.fields.get(key, None)
- if field and field.required and not context.get(key):
- context.pop(key, None)
- failed_to_contribute = set(self.contributes)
- failed_to_contribute -= set(context.keys())
- if failed_to_contribute:
- raise exceptions.WorkflowError("The following expected data was "
- "not added to the workflow context "
- "by the step %s: %s."
- % (self.__class__,
- failed_to_contribute))
- return True
-
- def contribute(self, data, context):
- """
- Adds the data listed in ``contributes`` to the workflow's shared
- context. By default, the context is simply updated with all the data
- returned by the action.
-
- Note that even if the value of one of the ``contributes`` keys is
- not present (e.g. optional) the key should still be added to the
- context with a value of ``None``.
- """
- if data:
- for key in self.contributes:
- context[key] = data.get(key, None)
- return context
-
- def render(self):
- """ Renders the step. """
- step_template = template.loader.get_template(self.template_name)
- extra_context = {"form": self.action,
- "step": self}
-
- # FIXME: TableStep:
- if issubclass(self.__class__, TableStep):
- extra_context.update(self.get_context_data(self.workflow.request))
-
- context = template.RequestContext(self.workflow.request, extra_context)
- return step_template.render(context)
-
- def get_help_text(self):
- """ Returns the help text for this step. """
- text = linebreaks(force_unicode(self.help_text))
- text += self.action.get_help_text()
- return safe(text)
-
- def add_error(self, message):
- """
- Adds an error to the Step based on API issues.
- """
- self.action.add_error(message)
-
-
-# FIXME: TableStep
-class TableStep(Step):
- """
- A :class:`~horizon.workflows.Step` class which knows how to deal with
- :class:`~horizon.tables.DataTable` classes rendered inside of it.
-
- This distinct class is required due to the complexity involved in handling
- both dynamic tab loading, dynamic table updating and table actions all
- within one view.
-
- .. attribute:: table_classes
-
- An iterable containing the :class:`~horizon.tables.DataTable` classes
- which this tab will contain. Equivalent to the
- :attr:`~horizon.tables.MultiTableView.table_classes` attribute on
- :class:`~horizon.tables.MultiTableView`. For each table class you
- need to define a corresponding ``get_{{ table_name }}_data`` method
- as with :class:`~horizon.tables.MultiTableView`.
- """
-
- table_classes = None
-
- def __init__(self, workflow):
- super(TableStep, self).__init__(workflow)
- if not self.table_classes:
- class_name = self.__class__.__name__
- raise NotImplementedError("You must define a table_class "
- "attribute on %s" % class_name)
- # Instantiate our table classes but don't assign data yet
- table_instances = [(table._meta.name,
- table(workflow.request, needs_form_wrapper=False))
- for table in self.table_classes]
- self._tables = SortedDict(table_instances)
- self._table_data_loaded = False
-
- def load_table_data(self):
- """
- Calls the ``get_{{ table_name }}_data`` methods for each table class
- and sets the data on the tables.
- """
- # We only want the data to be loaded once, so we track if we have...
- if not self._table_data_loaded:
- for table_name, table in self._tables.items():
- # Fetch the data function.
- func_name = "get_%s_data" % table_name
- data_func = getattr(self, func_name, None)
- if data_func is None:
- cls_name = self.__class__.__name__
- raise NotImplementedError("You must define a %s method "
- "on %s." % (func_name, cls_name))
- # Load the data.
- table.data = data_func()
- table._meta.has_more_data = self.has_more_data(table)
- # Mark our data as loaded so we don't run the loaders again.
- self._table_data_loaded = True
-
- def get_context_data(self, request):
- """
- Adds a ``{{ table_name }}_table`` item to the context for each table
- in the :attr:`~horizon.tabs.TableTab.table_classes` attribute.
-
- If only one table class is provided, a shortcut ``table`` context
- variable is also added containing the single table.
- """
- context = {}
- # If the data hasn't been manually loaded before now,
- # make certain it's loaded before setting the context.
- self.load_table_data()
- for table_name, table in self._tables.items():
- # If there's only one table class, add a shortcut name as well.
- if len(self.table_classes) == 1:
- context["table"] = table
- context["%s_table" % table_name] = table
- return context
-
- def has_more_data(self, table):
- return False
-
-
-class WorkflowMetaclass(type):
- def __new__(mcs, name, bases, attrs):
- super(WorkflowMetaclass, mcs).__new__(mcs, name, bases, attrs)
- attrs["_cls_registry"] = set([])
- return type.__new__(mcs, name, bases, attrs)
-
-
-class UpdateMembersStep(Step):
- """A step that allows a user to add/remove members from a group.
-
- .. attribute:: show_roles
-
- Set to False to disable the display of the roles dropdown.
-
- .. attribute:: available_list_title
-
- The title used for the available list column.
-
- .. attribute:: members_list_title
-
- The title used for the members list column.
-
- .. attribute:: no_available_text
-
- The placeholder text used when the available list is empty.
-
- .. attribute:: no_members_text
-
- The placeholder text used when the members list is empty.
-
- """
- template_name = "horizon/common/_workflow_step_update_members.html"
- show_roles = True
- available_list_title = _("All available")
- members_list_title = _("Members")
- no_available_text = _("None available.")
- no_members_text = _("No members.")
-
-
-class Workflow(html.HTMLElement):
- """
- A Workflow is a collection of Steps. It's interface is very
- straightforward, but it is responsible for handling some very
- important tasks such as:
-
- * Handling the injection, removal, and ordering of arbitrary steps.
-
- * Determining if the workflow can be completed by a given user at runtime
- based on all available information.
-
- * Dispatching connections between steps to ensure that when context data
- changes all the applicable callback functions are executed.
-
- * Verifying/validating the overall data integrity and subsequently
- triggering the final method to complete the workflow.
-
- The ``Workflow`` class has the following attributes:
-
- .. attribute:: name
-
- The verbose name for this workflow which will be displayed to the user.
- Defaults to the class name.
-
- .. attribute:: slug
-
- The unique slug for this workflow. Required.
-
- .. attribute:: steps
-
- Read-only access to the final ordered set of step instances for
- this workflow.
-
- .. attribute:: default_steps
-
- A list of :class:`~horizon.workflows.Step` classes which serve as the
- starting point for this workflow's ordered steps. Defaults to an empty
- list (``[]``).
-
- .. attribute:: finalize_button_name
-
- The name which will appear on the submit button for the workflow's
- form. Defaults to ``"Save"``.
-
- .. attribute:: success_message
-
- A string which will be displayed to the user upon successful completion
- of the workflow. Defaults to
- ``"{{ workflow.name }} completed successfully."``
-
- .. attribute:: failure_message
-
- A string which will be displayed to the user upon failure to complete
- the workflow. Defaults to ``"{{ workflow.name }} did not complete."``
-
- .. attribute:: depends_on
-
- A roll-up list of all the ``depends_on`` values compiled from the
- workflow's steps.
-
- .. attribute:: contributions
-
- A roll-up list of all the ``contributes`` values compiled from the
- workflow's steps.
-
- .. attribute:: template_name
-
- Path to the template which should be used to render this workflow.
- In general the default common template should be used. Default:
- ``"horizon/common/_workflow.html"``.
-
- .. attribute:: entry_point
-
- The slug of the step which should initially be active when the
- workflow is rendered. This can be passed in upon initialization of
- the workflow, or set anytime after initialization but before calling
- either ``get_entry_point`` or ``render``.
-
- .. attribute:: redirect_param_name
-
- The name of a parameter used for tracking the URL to redirect to upon
- completion of the workflow. Defaults to ``"next"``.
-
- .. attribute:: object
-
- The object (if any) which this workflow relates to. In the case of
- a workflow which creates a new resource the object would be the created
- resource after the relevant creation steps have been undertaken. In
- the case of a workflow which updates a resource it would be the
- resource being updated after it has been retrieved.
-
- """
- __metaclass__ = WorkflowMetaclass
- slug = None
- default_steps = ()
- template_name = "horizon/common/_workflow.html"
- finalize_button_name = _("Save")
- success_message = _("%s completed successfully.")
- failure_message = _("%s did not complete.")
- redirect_param_name = "next"
- multipart = False
- _registerable_class = Step
-
- def __unicode__(self):
- return self.name
-
- def __repr__(self):
- return "<%s: %s>" % (self.__class__.__name__, self.slug)
-
- def __init__(self, request=None, context_seed=None, entry_point=None,
- *args, **kwargs):
- super(Workflow, self).__init__(*args, **kwargs)
- if self.slug is None:
- raise AttributeError("The workflow %s must have a slug."
- % self.__class__.__name__)
- self.name = getattr(self, "name", self.__class__.__name__)
- self.request = request
- self.depends_on = set([])
- self.contributions = set([])
- self.entry_point = entry_point
- self.object = None
-
- # Put together our steps in order. Note that we pre-register
- # non-default steps so that we can identify them and subsequently
- # insert them in order correctly.
- self._registry = dict([(step_class, step_class(self)) for step_class
- in self.__class__._cls_registry
- if step_class not in self.default_steps])
- self._gather_steps()
-
- # Determine all the context data we need to end up with.
- for step in self.steps:
- self.depends_on = self.depends_on | set(step.depends_on)
- self.contributions = self.contributions | set(step.contributes)
-
- # Initialize our context. For ease we can preseed it with a
- # regular dictionary. This should happen after steps have been
- # registered and ordered.
- self.context = WorkflowContext(self)
- context_seed = context_seed or {}
- clean_seed = dict([(key, val)
- for key, val in context_seed.items()
- if key in self.contributions | self.depends_on])
- self.context_seed = clean_seed
- self.context.update(clean_seed)
-
- if request and request.method == "POST":
- for step in self.steps:
- valid = step.action.is_valid()
- # Be sure to use the CLEANED data if the workflow is valid.
- if valid:
- data = step.action.cleaned_data
- else:
- data = request.POST
- self.context = step.contribute(data, self.context)
-
- @property
- def steps(self):
- if getattr(self, "_ordered_steps", None) is None:
- self._gather_steps()
- return self._ordered_steps
-
- def get_step(self, slug):
- """ Returns the instantiated step matching the given slug. """
- for step in self.steps:
- if step.slug == slug:
- return step
-
- def _gather_steps(self):
- ordered_step_classes = self._order_steps()
- for default_step in self.default_steps:
- self.register(default_step)
- self._registry[default_step] = default_step(self)
- self._ordered_steps = [self._registry[step_class]
- for step_class in ordered_step_classes
- if has_permissions(self.request.user,
- self._registry[step_class])]
-
- def _order_steps(self):
- steps = list(copy.copy(self.default_steps))
- additional = self._registry.keys()
- for step in additional:
- try:
- min_pos = steps.index(step.after)
- except ValueError:
- min_pos = 0
- try:
- max_pos = steps.index(step.before)
- except ValueError:
- max_pos = len(steps)
- if min_pos > max_pos:
- raise exceptions.WorkflowError("The step %(new)s can't be "
- "placed between the steps "
- "%(after)s and %(before)s; the "
- "step %(before)s comes before "
- "%(after)s."
- % {"new": additional,
- "after": step.after,
- "before": step.before})
- steps.insert(max_pos, step)
- return steps
-
- def get_entry_point(self):
- """
- Returns the slug of the step which the workflow should begin on.
-
- This method takes into account both already-available data and errors
- within the steps.
- """
- # If we have a valid specified entry point, use it.
- if self.entry_point:
- if self.get_step(self.entry_point):
- return self.entry_point
- # Otherwise fall back to calculating the appropriate entry point.
- for step in self.steps:
- if step.has_errors:
- return step.slug
- try:
- step._verify_contributions(self.context)
- except exceptions.WorkflowError:
- return step.slug
- # If nothing else, just return the first step.
- return self.steps[0].slug
-
- def _trigger_handlers(self, key):
- responses = []
- handlers = [(step.slug, f) for step in self.steps
- for f in step._handlers.get(key, [])]
- for slug, handler in handlers:
- responses.append((slug, handler(self.request, self.context)))
- return responses
-
- @classmethod
- def register(cls, step_class):
- """ Registers a :class:`~horizon.workflows.Step` with the workflow. """
- if not inspect.isclass(step_class):
- raise ValueError('Only classes may be registered.')
- elif not issubclass(step_class, cls._registerable_class):
- raise ValueError('Only %s classes or subclasses may be registered.'
- % cls._registerable_class.__name__)
- if step_class in cls._cls_registry:
- return False
- else:
- cls._cls_registry.add(step_class)
- return True
-
- @classmethod
- def unregister(cls, step_class):
- """
- Unregisters a :class:`~horizon.workflows.Step` from the workflow.
- """
- try:
- cls._cls_registry.remove(step_class)
- except KeyError:
- raise base.NotRegistered('%s is not registered' % cls)
- return cls._unregister(step_class)
-
- def validate(self, context):
- """
- Hook for custom context data validation. Should return a boolean
- value or raise :class:`~horizon.exceptions.WorkflowValidationError`.
- """
- return True
-
- def is_valid(self):
- """
- Verified that all required data is present in the context and
- calls the ``validate`` method to allow for finer-grained checks
- on the context data.
- """
- missing = self.depends_on - set(self.context.keys())
- if missing:
- raise exceptions.WorkflowValidationError(
- "Unable to complete the workflow. The values %s are "
- "required but not present." % ", ".join(missing))
-
- # Validate each step. Cycle through all of them to catch all errors
- # in one pass before returning.
- steps_valid = True
- for step in self.steps:
- if not step.action.is_valid():
- steps_valid = False
- step.has_errors = True
- if not steps_valid:
- return steps_valid
- return self.validate(self.context)
-
- def finalize(self):
- """
- Finalizes a workflow by running through all the actions in order
- and calling their ``handle`` methods. Returns ``True`` on full success,
- or ``False`` for a partial success, e.g. there were non-critical
- errors. (If it failed completely the function wouldn't return.)
- """
- partial = False
- for step in self.steps:
- try:
- data = step.action.handle(self.request, self.context)
- if data is True or data is None:
- continue
- elif data is False:
- partial = True
- else:
- self.context = step.contribute(data or {}, self.context)
- except:
- partial = True
- exceptions.handle(self.request)
- if not self.handle(self.request, self.context):
- partial = True
- return not partial
-
- def handle(self, request, context):
- """
- Handles any final processing for this workflow. Should return a boolean
- value indicating success.
- """
- return True
-
- def get_success_url(self):
- """
- Returns a URL to redirect the user to upon completion. By default it
- will attempt to parse a ``success_url`` attribute on the workflow,
- which can take the form of a reversible URL pattern name, or a
- standard HTTP URL.
- """
- try:
- return urlresolvers.reverse(self.success_url)
- except urlresolvers.NoReverseMatch:
- return self.success_url
-
- def format_status_message(self, message):
- """
- Hook to allow customization of the message returned to the user
- upon successful or unsuccessful completion of the workflow.
-
- By default it simply inserts the workflow's name into the message
- string.
- """
- if "%s" in message:
- return message % self.name
- else:
- return message
-
- def render(self):
- """ Renders the workflow. """
- workflow_template = template.loader.get_template(self.template_name)
- extra_context = {"workflow": self}
- if self.request.is_ajax():
- extra_context['modal'] = True
- context = template.RequestContext(self.request, extra_context)
- return workflow_template.render(context)
-
- def get_absolute_url(self):
- """ Returns the canonical URL for this workflow.
-
- This is used for the POST action attribute on the form element
- wrapping the workflow.
-
- For convenience it defaults to the value of
- ``request.get_full_path()`` with any query string stripped off,
- e.g. the path at which the workflow was requested.
- """
- return self.request.get_full_path().partition('?')[0]
-
- def add_error_to_step(self, message, slug):
- """
- Adds an error to the workflow's Step with the
- specifed slug based on API issues. This is useful
- when you wish for API errors to appear as errors on
- the form rather than using the messages framework.
- """
- step = self.get_step(slug)
- if step:
- step.add_error(message)
diff --git a/horizon/workflows/views.py b/horizon/workflows/views.py
deleted file mode 100644
index 6bfb339f..00000000
--- a/horizon/workflows/views.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import copy
-import json
-
-from django import http
-from django import shortcuts
-from django.views import generic
-
-from horizon import exceptions
-from horizon.forms.views import ADD_TO_FIELD_HEADER
-from horizon import messages
-
-
-class WorkflowView(generic.TemplateView):
- """
- A generic class-based view which handles the intricacies of workflow
- processing with minimal user configuration.
-
- .. attribute:: workflow_class
-
- The :class:`~horizon.workflows.Workflow` class which this view handles.
- Required.
-
- .. attribute:: template_name
-
- The template to use when rendering this view via standard HTTP
- requests. Required.
-
- .. attribute:: ajax_template_name
-
- The template to use when rendering the workflow for AJAX requests.
- In general the default common template should be used. Defaults to
- ``"horizon/common/_workflow.html"``.
-
- .. attribute:: context_object_name
-
- The key which should be used for the workflow object in the template
- context. Defaults to ``"workflow"``.
-
- """
- workflow_class = None
- template_name = 'horizon/common/_workflow_base.html'
- context_object_name = "workflow"
- ajax_template_name = 'horizon/common/_workflow.html'
- step_errors = {}
-
- def __init__(self):
- if not self.workflow_class:
- raise AttributeError("You must set the workflow_class attribute "
- "on %s." % self.__class__.__name__)
-
- def get_initial(self):
- """
- Returns initial data for the workflow. Defaults to using the GET
- parameters to allow pre-seeding of the workflow context values.
- """
- return copy.copy(self.request.GET)
-
- def get_workflow(self):
- """ Returns the instanciated workflow class. """
- extra_context = self.get_initial()
- entry_point = self.request.GET.get("step", None)
- workflow = self.workflow_class(self.request,
- context_seed=extra_context,
- entry_point=entry_point)
- return workflow
-
- def get_context_data(self, **kwargs):
- """
- Returns the template context, including the workflow class.
-
- This method should be overridden in subclasses to provide additional
- context data to the template.
- """
- context = super(WorkflowView, self).get_context_data(**kwargs)
- workflow = self.get_workflow()
- context[self.context_object_name] = workflow
- next = self.request.REQUEST.get(workflow.redirect_param_name, None)
- context['REDIRECT_URL'] = next
- if self.request.is_ajax():
- context['modal'] = True
- if ADD_TO_FIELD_HEADER in self.request.META:
- context['add_to_field'] = self.request.META[ADD_TO_FIELD_HEADER]
- return context
-
- def get_template_names(self):
- """ Returns the template name to use for this request. """
- if self.request.is_ajax():
- template = self.ajax_template_name
- else:
- template = self.template_name
- return template
-
- def get_object_id(self, obj):
- return getattr(obj, "id", None)
-
- def get_object_display(self, obj):
- return getattr(obj, "name", None)
-
- def add_error_to_step(self, error_msg, step):
- self.step_errors[step] = error_msg
-
- def set_workflow_step_errors(self, context):
- workflow = context['workflow']
- for step in self.step_errors:
- error_msg = self.step_errors[step]
- workflow.add_error_to_step(error_msg, step)
-
- def get(self, request, *args, **kwargs):
- """ Handler for HTTP GET requests. """
- context = self.get_context_data(**kwargs)
- self.set_workflow_step_errors(context)
- return self.render_to_response(context)
-
- def post(self, request, *args, **kwargs):
- """ Handler for HTTP POST requests. """
- context = self.get_context_data(**kwargs)
- workflow = context[self.context_object_name]
- if workflow.is_valid():
- try:
- success = workflow.finalize()
- except:
- success = False
- exceptions.handle(request)
- next = self.request.REQUEST.get(workflow.redirect_param_name, None)
- if success:
- msg = workflow.format_status_message(workflow.success_message)
- messages.success(request, msg)
- else:
- msg = workflow.format_status_message(workflow.failure_message)
- messages.error(request, msg)
-
- if "HTTP_X_HORIZON_ADD_TO_FIELD" in self.request.META:
- field_id = self.request.META["HTTP_X_HORIZON_ADD_TO_FIELD"]
- data = [self.get_object_id(workflow.object),
- self.get_object_display(workflow.object)]
- response = http.HttpResponse(json.dumps(data))
- response["X-Horizon-Add-To-Field"] = field_id
- return response
- else:
- return shortcuts.redirect(next or workflow.get_success_url())
- else:
- return self.render_to_response(context)
diff --git a/openstack-common.conf b/openstack-common.conf
deleted file mode 100644
index aa99f1b1..00000000
--- a/openstack-common.conf
+++ /dev/null
@@ -1,9 +0,0 @@
-[DEFAULT]
-module=eventlet_backdoor
-module=notifier
-module=rpc
-module=service
-module=threadgroup
-module=config
-
-base=openstack_dashboard
diff --git a/openstack_dashboard/__init__.py b/openstack_dashboard/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/api/__init__.py b/openstack_dashboard/api/__init__.py
deleted file mode 100644
index 50e764f2..00000000
--- a/openstack_dashboard/api/__init__.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-# Copyright 2013 Big Switch Networks
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Methods and interface objects used to interact with external APIs.
-
-API method calls return objects that are in many cases objects with
-attributes that are direct maps to the data returned from the API http call.
-Unfortunately, these objects are also often constructed dynamically, making
-it difficult to know what data is available from the API object. Because of
-this, all API calls should wrap their returned object in one defined here,
-using only explicitly defined atributes and/or methods.
-
-In other words, Horizon developers not working on openstack_dashboard.api
-shouldn't need to understand the finer details of APIs for
-Keystone/Nova/Glance/Swift et. al.
-"""
-from openstack_dashboard.api import base
-from openstack_dashboard.api import cinder
-from openstack_dashboard.api import glance
-from openstack_dashboard.api import heat
-from openstack_dashboard.api import keystone
-from openstack_dashboard.api import lbaas
-from openstack_dashboard.api import network
-from openstack_dashboard.api import neutron
-from openstack_dashboard.api import nova
-from openstack_dashboard.api import swift
-from openstack_dashboard.api import tuskar
-
-assert base
-assert cinder
-assert heat
-assert glance
-assert keystone
-assert network
-assert nova
-assert neutron
-assert lbaas
-assert swift
-assert tuskar
diff --git a/openstack_dashboard/api/base.py b/openstack_dashboard/api/base.py
deleted file mode 100644
index 3edb5226..00000000
--- a/openstack_dashboard/api/base.py
+++ /dev/null
@@ -1,263 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from collections import Sequence
-import logging
-
-from django.conf import settings
-
-from horizon import exceptions
-
-
-__all__ = ('APIResourceWrapper', 'APIDictWrapper',
- 'get_service_from_catalog', 'url_for',)
-
-
-LOG = logging.getLogger(__name__)
-
-
-class APIVersionManager(object):
- """ Object to store and manage API versioning data and utility methods. """
-
- SETTINGS_KEY = "OPENSTACK_API_VERSIONS"
-
- def __init__(self, service_type, preferred_version=None):
- self.service_type = service_type
- self.preferred = preferred_version
- self._active = None
- self.supported = {}
-
- @property
- def active(self):
- if self._active is None:
- self.get_active_version()
- return self._active
-
- def load_supported_version(self, version, data):
- self.supported[version] = data
-
- def get_active_version(self):
- if self._active is not None:
- return self.supported[self._active]
- key = getattr(settings, self.SETTINGS_KEY, {}).get(self.service_type)
- if key is None:
- # TODO(gabriel): support API version discovery here; we'll leave
- # the setting in as a way of overriding the latest available
- # version.
- key = self.preferred
- self._active = key
- return self.supported[self._active]
-
-
-class APIResourceWrapper(object):
- """ Simple wrapper for api objects
-
- Define _attrs on the child class and pass in the
- api object as the only argument to the constructor
- """
- _attrs = []
-
- def __init__(self, apiresource):
- self._apiresource = apiresource
-
- def __getattr__(self, attr):
- if attr in self._attrs:
- # __getattr__ won't find properties
- return self._apiresource.__getattribute__(attr)
- else:
- msg = ('Attempted to access unknown attribute "%s" on '
- 'APIResource object of type "%s" wrapping resource of '
- 'type "%s".') % (attr, self.__class__,
- self._apiresource.__class__)
- LOG.debug(exceptions.error_color(msg))
- raise AttributeError(attr)
-
- def __repr__(self):
- return "<%s: %s>" % (self.__class__.__name__,
- dict((attr, getattr(self, attr))
- for attr in self._attrs
- if hasattr(self, attr)))
-
-
-class APIDictWrapper(object):
- """ Simple wrapper for api dictionaries
-
- Some api calls return dictionaries. This class provides identical
- behavior as APIResourceWrapper, except that it will also behave as a
- dictionary, in addition to attribute accesses.
-
- Attribute access is the preferred method of access, to be
- consistent with api resource objects from novaclient.
- """
- def __init__(self, apidict):
- self._apidict = apidict
-
- def __getattr__(self, attr):
- try:
- return self._apidict[attr]
- except KeyError:
- msg = 'Unknown attribute "%(attr)s" on APIResource object ' \
- 'of type "%(cls)s"' % {'attr': attr, 'cls': self.__class__}
- LOG.debug(exceptions.error_color(msg))
- raise AttributeError(msg)
-
- def __getitem__(self, item):
- try:
- return self.__getattr__(item)
- except AttributeError as e:
- # caller is expecting a KeyError
- raise KeyError(e)
-
- def get(self, item, default=None):
- try:
- return self.__getattr__(item)
- except AttributeError:
- return default
-
- def __repr__(self):
- return "<%s: %s>" % (self.__class__.__name__, self._apidict)
-
-
-class Quota(object):
- """Wrapper for individual limits in a quota."""
- def __init__(self, name, limit):
- self.name = name
- self.limit = limit
-
- def __repr__(self):
- return "<Quota: (%s, %s)>" % (self.name, self.limit)
-
-
-class QuotaSet(Sequence):
- """
- Wrapper for client QuotaSet objects which turns the individual quotas
- into Quota objects for easier handling/iteration.
-
- `QuotaSet` objects support a mix of `list` and `dict` methods; you can use
- the bracket notiation (`qs["my_quota"] = 0`) to add new quota values, and
- use the `get` method to retrieve a specific quota, but otherwise it
- behaves much like a list or tuple, particularly in supporting iteration.
- """
- def __init__(self, apiresource=None):
- self.items = []
- if apiresource:
- for k, v in apiresource._info.items():
- if k == 'id':
- continue
- self[k] = v
-
- def __setitem__(self, k, v):
- v = int(v) if v is not None else v
- q = Quota(k, v)
- self.items.append(q)
-
- def __getitem__(self, index):
- return self.items[index]
-
- def __len__(self):
- return len(self.items)
-
- def __repr__(self):
- return repr(self.items)
-
- def get(self, key, default=None):
- match = [quota for quota in self.items if quota.name == key]
- return match.pop() if len(match) else Quota(key, default)
-
-
-def get_service_from_catalog(catalog, service_type):
- if catalog:
- for service in catalog:
- if service['type'] == service_type:
- return service
- return None
-
-
-def get_version_from_service(service):
- if service:
- endpoint = service['endpoints'][0]
- if 'interface' in endpoint:
- return 3
- else:
- return 2.0
- return 2.0
-
-
-# Mapping of V2 Catalog Endpoint_type to V3 Catalog Interfaces
-ENDPOINT_TYPE_TO_INTERFACE = {
- 'publicURL': 'public',
- 'internalURL': 'internal',
- 'adminURL': 'admin',
-}
-
-
-def get_url_for_service(service, region, endpoint_type):
- identity_version = get_version_from_service(service)
- for endpoint in service['endpoints']:
- # ignore region for identity
- if service['type'] == 'identity' or region == endpoint['region']:
- try:
- if identity_version < 3:
- return endpoint[endpoint_type]
- else:
- interface = \
- ENDPOINT_TYPE_TO_INTERFACE.get(endpoint_type, '')
- if endpoint['interface'] == interface:
- return endpoint['url']
- except (IndexError, KeyError):
- return None
- return None
-
-
-def url_for(request, service_type, endpoint_type=None):
- endpoint_type = endpoint_type or getattr(settings,
- 'OPENSTACK_ENDPOINT_TYPE',
- 'publicURL')
- fallback_endpoint_type = getattr(settings, 'SECONDARY_ENDPOINT_TYPE', None)
-
- catalog = request.user.service_catalog
- service = get_service_from_catalog(catalog, service_type)
- if service:
- url = get_url_for_service(service,
- request.user.services_region,
- endpoint_type)
- if not url and fallback_endpoint_type:
- url = get_url_for_service(service,
- request.user.services_region,
- fallback_endpoint_type)
- if url:
- return url
- raise exceptions.ServiceCatalogException(service_type)
-
-
-def is_service_enabled(request, service_type, service_name=None):
- service = get_service_from_catalog(request.user.service_catalog,
- service_type)
- if service:
- region = request.user.services_region
- for endpoint in service['endpoints']:
- # ignore region for identity
- if service['type'] == 'identity' or \
- endpoint['region'] == region:
- if service_name:
- return service['name'] == service_name
- else:
- return True
- return False
diff --git a/openstack_dashboard/api/cinder.py b/openstack_dashboard/api/cinder.py
deleted file mode 100644
index aa6b7740..00000000
--- a/openstack_dashboard/api/cinder.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Openstack, LLC
-# Copyright 2012 Nebula, Inc.
-# Copyright (c) 2012 X.commerce, a business unit of eBay Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from __future__ import absolute_import
-
-import logging
-
-from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
-
-from cinderclient.v1 import client as cinder_client
-
-from horizon import exceptions
-
-from openstack_dashboard.api.base import QuotaSet
-from openstack_dashboard.api.base import url_for
-from openstack_dashboard.api import nova
-
-LOG = logging.getLogger(__name__)
-
-
-# API static values
-VOLUME_STATE_AVAILABLE = "available"
-
-
-def cinderclient(request):
- insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
- cinder_url = ""
- try:
- cinder_url = url_for(request, 'volume')
- except exceptions.ServiceCatalogException:
- LOG.debug('no volume service configured.')
- return None
- LOG.debug('cinderclient connection created using token "%s" and url "%s"' %
- (request.user.token.id, cinder_url))
- c = cinder_client.Client(request.user.username,
- request.user.token.id,
- project_id=request.user.tenant_id,
- auth_url=cinder_url,
- insecure=insecure,
- http_log_debug=settings.DEBUG)
- c.client.auth_token = request.user.token.id
- c.client.management_url = cinder_url
- return c
-
-
-def volume_list(request, search_opts=None):
- """
- To see all volumes in the cloud as an admin you can pass in a special
- search option: {'all_tenants': 1}
- """
- c_client = cinderclient(request)
- if c_client is None:
- return []
- return c_client.volumes.list(search_opts=search_opts)
-
-
-def volume_get(request, volume_id):
- volume_data = cinderclient(request).volumes.get(volume_id)
-
- for attachment in volume_data.attachments:
- if "server_id" in attachment:
- instance = nova.server_get(request, attachment['server_id'])
- attachment['instance_name'] = instance.name
- else:
- # Nova volume can occasionally send back error'd attachments
- # the lack a server_id property; to work around that we'll
- # give the attached instance a generic name.
- attachment['instance_name'] = _("Unknown instance")
- return volume_data
-
-
-def volume_create(request, size, name, description, volume_type,
- snapshot_id=None, metadata=None, image_id=None):
- return cinderclient(request).volumes.create(size, display_name=name,
- display_description=description, volume_type=volume_type,
- snapshot_id=snapshot_id, metadata=metadata, imageRef=image_id)
-
-
-def volume_delete(request, volume_id):
- return cinderclient(request).volumes.delete(volume_id)
-
-
-def volume_snapshot_get(request, snapshot_id):
- return cinderclient(request).volume_snapshots.get(snapshot_id)
-
-
-def volume_snapshot_list(request):
- c_client = cinderclient(request)
- if c_client is None:
- return []
- return c_client.volume_snapshots.list()
-
-
-def volume_snapshot_create(request, volume_id, name, description):
- return cinderclient(request).volume_snapshots.create(
- volume_id, display_name=name, display_description=description)
-
-
-def volume_snapshot_delete(request, snapshot_id):
- return cinderclient(request).volume_snapshots.delete(snapshot_id)
-
-
-def tenant_quota_get(request, tenant_id):
- c_client = cinderclient(request)
- if c_client is None:
- return QuotaSet()
- return QuotaSet(c_client.quotas.get(tenant_id))
-
-
-def tenant_quota_update(request, tenant_id, **kwargs):
- return cinderclient(request).quotas.update(tenant_id, **kwargs)
-
-
-def default_quota_get(request, tenant_id):
- return QuotaSet(cinderclient(request).quotas.defaults(tenant_id))
-
-
-def volume_type_list(request):
- return cinderclient(request).volume_types.list()
-
-
-def volume_type_create(request, name):
- return cinderclient(request).volume_types.create(name)
-
-
-def volume_type_delete(request, volume_type_id):
- return cinderclient(request).volume_types.delete(volume_type_id)
-
-
-def tenant_absolute_limits(request):
- limits = cinderclient(request).limits.get().absolute
- limits_dict = {}
- for limit in limits:
- # -1 is used to represent unlimited quotas
- if limit.value == -1:
- limits_dict[limit.name] = float("inf")
- else:
- limits_dict[limit.name] = limit.value
- return limits_dict
diff --git a/openstack_dashboard/api/glance.py b/openstack_dashboard/api/glance.py
deleted file mode 100644
index 1537acac..00000000
--- a/openstack_dashboard/api/glance.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from __future__ import absolute_import
-
-import itertools
-import logging
-import thread
-import urlparse
-
-from django.conf import settings
-
-import glanceclient as glance_client
-
-from openstack_dashboard.api.base import url_for
-
-
-LOG = logging.getLogger(__name__)
-
-
-def glanceclient(request):
- o = urlparse.urlparse(url_for(request, 'image'))
- url = "://".join((o.scheme, o.netloc))
- insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
- LOG.debug('glanceclient connection created using token "%s" and url "%s"'
- % (request.user.token.id, url))
- return glance_client.Client('1', url, token=request.user.token.id,
- insecure=insecure)
-
-
-def image_delete(request, image_id):
- return glanceclient(request).images.delete(image_id)
-
-
-def image_get(request, image_id):
- """
- Returns an Image object populated with metadata for image
- with supplied identifier.
- """
- return glanceclient(request).images.get(image_id)
-
-
-def image_list_detailed(request, marker=None, filters=None, paginate=False):
- limit = getattr(settings, 'API_RESULT_LIMIT', 1000)
- page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 20)
-
- if paginate:
- request_size = page_size + 1
- else:
- request_size = limit
-
- kwargs = {'filters': filters or {}}
- if marker:
- kwargs['marker'] = marker
-
- images_iter = glanceclient(request).images.list(page_size=request_size,
- limit=limit,
- **kwargs)
- has_more_data = False
- if paginate:
- images = list(itertools.islice(images_iter, request_size))
- if len(images) > page_size:
- images.pop(-1)
- has_more_data = True
- else:
- images = list(images_iter)
- return (images, has_more_data)
-
-
-def image_update(request, image_id, **kwargs):
- return glanceclient(request).images.update(image_id, **kwargs)
-
-
-def image_create(request, **kwargs):
- copy_from = None
-
- if kwargs.get('copy_from'):
- copy_from = kwargs.pop('copy_from')
-
- image = glanceclient(request).images.create(**kwargs)
-
- if copy_from:
- thread.start_new_thread(image_update,
- (request, image.id),
- {'copy_from': copy_from})
-
- return image
diff --git a/openstack_dashboard/api/heat.py b/openstack_dashboard/api/heat.py
deleted file mode 100644
index 815b0963..00000000
--- a/openstack_dashboard/api/heat.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.conf import settings
-from heatclient import client as heat_client
-from openstack_dashboard.api.base import url_for
-
-LOG = logging.getLogger(__name__)
-
-
-def format_parameters(params):
- parameters = {}
- for count, p in enumerate(params, 1):
- parameters['Parameters.member.%d.ParameterKey' % count] = p
- parameters['Parameters.member.%d.ParameterValue' % count] = params[p]
- return parameters
-
-
-def heatclient(request, password=None):
- api_version = "1"
- insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
- endpoint = url_for(request, 'orchestration')
- LOG.debug('heatclient connection created using token "%s" and url "%s"' %
- (request.user.token.id, endpoint))
- kwargs = {
- 'token': request.user.token.id,
- 'insecure': insecure,
- 'username': request.user.username,
- 'password': password
- #'timeout': args.timeout,
- #'ca_file': args.ca_file,
- #'cert_file': args.cert_file,
- #'key_file': args.key_file,
- }
- client = heat_client.Client(api_version, endpoint, **kwargs)
- client.format_parameters = format_parameters
- return client
-
-
-def stacks_list(request):
- return heatclient(request).stacks.list()
-
-
-def stack_delete(request, stack_id):
- return heatclient(request).stacks.delete(stack_id)
-
-
-def stack_get(request, stack_id):
- return heatclient(request).stacks.get(stack_id)
-
-
-def stack_create(request, password=None, **kwargs):
- return heatclient(request, password).stacks.create(**kwargs)
-
-
-def events_list(request, stack_name):
- return heatclient(request).events.list(stack_name)
-
-
-def resources_list(request, stack_name):
- return heatclient(request).resources.list(stack_name)
-
-
-def resource_get(request, stack_id, resource_name):
- return heatclient(request).resources.get(stack_id, resource_name)
-
-
-def resource_metadata_get(request, stack_id, resource_name):
- return heatclient(request).resources.metadata(stack_id, resource_name)
-
-
-def template_validate(request, **kwargs):
- return heatclient(request).stacks.validate(**kwargs)
diff --git a/openstack_dashboard/api/keystone.py b/openstack_dashboard/api/keystone.py
deleted file mode 100644
index 87d112a7..00000000
--- a/openstack_dashboard/api/keystone.py
+++ /dev/null
@@ -1,545 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Openstack, LLC
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-import urlparse
-
-from django.conf import settings
-from django.contrib.auth import logout
-from django.utils.translation import ugettext_lazy as _
-
-from keystoneclient.exceptions import ClientException
-
-from openstack_auth.backend import KEYSTONE_CLIENT_ATTR
-
-from horizon import exceptions
-from horizon import messages
-
-from openstack_dashboard.api import base
-
-
-LOG = logging.getLogger(__name__)
-DEFAULT_ROLE = None
-
-
-# Set up our data structure for managing Identity API versions, and
-# add a couple utility methods to it.
-class IdentityAPIVersionManager(base.APIVersionManager):
- def upgrade_v2_user(self, user):
- if getattr(user, "project_id", None) is None:
- user.project_id = getattr(user, "tenantId", None)
- return user
-
- def get_project_manager(self, *args, **kwargs):
- if VERSIONS.active < 3:
- manager = keystoneclient(*args, **kwargs).tenants
- else:
- manager = keystoneclient(*args, **kwargs).projects
- return manager
-
-
-VERSIONS = IdentityAPIVersionManager("identity", preferred_version=3)
-
-
-# Import from oldest to newest so that "preferred" takes correct precedence.
-try:
- from keystoneclient.v2_0 import client as keystone_client_v2
- VERSIONS.load_supported_version(2.0, {"client": keystone_client_v2})
-except ImportError:
- pass
-
-try:
- from keystoneclient.v3 import client as keystone_client_v3
- VERSIONS.load_supported_version(3, {"client": keystone_client_v3})
-except ImportError:
- pass
-
-
-class Service(base.APIDictWrapper):
- """ Wrapper for a dict based on the service data from keystone. """
- _attrs = ['id', 'type', 'name']
-
- def __init__(self, service, region, *args, **kwargs):
- super(Service, self).__init__(service, *args, **kwargs)
- self.public_url = base.get_url_for_service(service, region,
- 'publicURL')
- self.url = base.get_url_for_service(service, region, 'internalURL')
- if self.url:
- self.host = urlparse.urlparse(self.url).hostname
- else:
- self.host = None
- self.disabled = None
- self.region = region
-
- def __unicode__(self):
- if(self.type == "identity"):
- return _("%(type)s (%(backend)s backend)") \
- % {"type": self.type, "backend": keystone_backend_name()}
- else:
- return self.type
-
- def __repr__(self):
- return "<Service: %s>" % unicode(self)
-
-
-def _get_endpoint_url(request, endpoint_type, catalog=None):
- if getattr(request.user, "service_catalog", None):
- url = base.url_for(request,
- service_type='identity',
- endpoint_type=endpoint_type)
- else:
- auth_url = getattr(settings, 'OPENSTACK_KEYSTONE_URL')
- url = request.session.get('region_endpoint', auth_url)
-
- # TODO(gabriel): When the Service Catalog no longer contains API versions
- # in the endpoints this can be removed.
- bits = urlparse.urlparse(url)
- root = "://".join((bits.scheme, bits.netloc))
- url = "%s/v%s" % (root, VERSIONS.active)
-
- return url
-
-
-def keystoneclient(request, admin=False):
- """Returns a client connected to the Keystone backend.
-
- Several forms of authentication are supported:
-
- * Username + password -> Unscoped authentication
- * Username + password + tenant id -> Scoped authentication
- * Unscoped token -> Unscoped authentication
- * Unscoped token + tenant id -> Scoped authentication
- * Scoped token -> Scoped authentication
-
- Available services and data from the backend will vary depending on
- whether the authentication was scoped or unscoped.
-
- Lazy authentication if an ``endpoint`` parameter is provided.
-
- Calls requiring the admin endpoint should have ``admin=True`` passed in
- as a keyword argument.
-
- The client is cached so that subsequent API calls during the same
- request/response cycle don't have to be re-authenticated.
- """
- user = request.user
- if admin:
- if not user.is_superuser:
- raise exceptions.NotAuthorized
- endpoint_type = 'adminURL'
- else:
- endpoint_type = getattr(settings,
- 'OPENSTACK_ENDPOINT_TYPE',
- 'internalURL')
-
- api_version = VERSIONS.get_active_version()
-
- # Take care of client connection caching/fetching a new client.
- # Admin vs. non-admin clients are cached separately for token matching.
- cache_attr = "_keystoneclient_admin" if admin else KEYSTONE_CLIENT_ATTR
- if hasattr(request, cache_attr) and (not user.token.id
- or getattr(request, cache_attr).auth_token == user.token.id):
- LOG.debug("Using cached client for token: %s" % user.token.id)
- conn = getattr(request, cache_attr)
- else:
- endpoint = _get_endpoint_url(request, endpoint_type)
- insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
- LOG.debug("Creating a new keystoneclient connection to %s." % endpoint)
- remote_addr = request.environ.get('REMOTE_ADDR', '')
- conn = api_version['client'].Client(token=user.token.id,
- endpoint=endpoint,
- original_ip=remote_addr,
- insecure=insecure,
- auth_url=endpoint,
- debug=settings.DEBUG)
- setattr(request, cache_attr, conn)
- return conn
-
-
-def domain_create(request, name, description=None, enabled=None):
- manager = keystoneclient(request, admin=True).domains
- return manager.create(name,
- description=description,
- enabled=enabled)
-
-
-def domain_get(request, domain_id):
- manager = keystoneclient(request, admin=True).domains
- return manager.get(domain_id)
-
-
-def domain_delete(request, domain_id):
- manager = keystoneclient(request, admin=True).domains
- return manager.delete(domain_id)
-
-
-def domain_list(request):
- manager = keystoneclient(request, admin=True).domains
- return manager.list()
-
-
-def domain_update(request, domain_id, name=None, description=None,
- enabled=None):
- manager = keystoneclient(request, admin=True).domains
- return manager.update(domain_id, name, description, enabled)
-
-
-def tenant_create(request, name, description=None, enabled=None, domain=None):
- manager = VERSIONS.get_project_manager(request, admin=True)
- if VERSIONS.active < 3:
- return manager.create(name, description, enabled)
- else:
- return manager.create(name, domain,
- description=description,
- enabled=enabled)
-
-
-# TODO(gabriel): Is there ever a valid case for admin to be false here?
-# A quick search through the codebase reveals that it's always called with
-# admin=true so I suspect we could eliminate it entirely as with the other
-# tenant commands.
-def tenant_get(request, project, admin=True):
- manager = VERSIONS.get_project_manager(request, admin=admin)
- return manager.get(project)
-
-
-def tenant_delete(request, project):
- manager = VERSIONS.get_project_manager(request, admin=True)
- return manager.delete(project)
-
-
-def tenant_list(request, paginate=False, marker=None, domain=None, user=None):
- manager = VERSIONS.get_project_manager(request, admin=True)
- page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 20)
- limit = None
- if paginate:
- limit = page_size + 1
-
- has_more_data = False
- if VERSIONS.active < 3:
- tenants = manager.list(limit, marker)
- if paginate and len(tenants) > page_size:
- tenants.pop(-1)
- has_more_data = True
- else:
- tenants = manager.list(domain=domain, user=user)
- return (tenants, has_more_data)
-
-
-def tenant_update(request, project, name=None, description=None,
- enabled=None, domain=None):
- manager = VERSIONS.get_project_manager(request, admin=True)
- if VERSIONS.active < 3:
- return manager.update(project, name, description, enabled)
- else:
- return manager.update(project, name=name, description=description,
- enabled=enabled, domain=domain)
-
-
-def user_list(request, project=None, domain=None, group=None):
- if VERSIONS.active < 3:
- kwargs = {"tenant_id": project}
- else:
- kwargs = {
- "project": project,
- "domain": domain,
- "group": group
- }
- users = keystoneclient(request, admin=True).users.list(**kwargs)
- return [VERSIONS.upgrade_v2_user(user) for user in users]
-
-
-def user_create(request, name=None, email=None, password=None, project=None,
- enabled=None, domain=None):
- manager = keystoneclient(request, admin=True).users
- if VERSIONS.active < 3:
- user = manager.create(name, password, email, project, enabled)
- return VERSIONS.upgrade_v2_user(user)
- else:
- return manager.create(name, password=password, email=email,
- project=project, enabled=enabled, domain=domain)
-
-
-def user_delete(request, user_id):
- return keystoneclient(request, admin=True).users.delete(user_id)
-
-
-def user_get(request, user_id, admin=True):
- user = keystoneclient(request, admin=admin).users.get(user_id)
- return VERSIONS.upgrade_v2_user(user)
-
-
-def user_update(request, user, **data):
- manager = keystoneclient(request, admin=True).users
- error = None
-
- if not keystone_can_edit_user():
- raise ClientException(405, _("Identity service does not allow "
- "editing user data."))
-
- # The v2 API updates user model, password and default project separately
- if VERSIONS.active < 3:
- password = data.pop('password')
- project = data.pop('project')
-
- # Update user details
- try:
- user = manager.update(user, **data)
- except:
- error = exceptions.handle(request, ignore=True)
-
- # Update default tenant
- try:
- user_update_tenant(request, user, project)
- user.tenantId = project
- except:
- error = exceptions.handle(request, ignore=True)
-
- # Check for existing roles
- # Show a warning if no role exists for the project
- user_roles = roles_for_user(request, user, project)
- if not user_roles:
- messages.warning(request,
- _('User %s has no role defined for '
- 'that project.')
- % data.get('name', None))
-
- # If present, update password
- # FIXME(gabriel): password change should be its own form + view
- if password:
- try:
- user_update_password(request, user, password)
- if user == request.user.id:
- logout(request)
- except:
- error = exceptions.handle(request, ignore=True)
-
- if error is not None:
- raise error
-
- # v3 API is so much simpler...
- else:
- if not data['password']:
- data.pop('password')
- user = manager.update(user, **data)
-
- return VERSIONS.upgrade_v2_user(user)
-
-
-def user_update_enabled(request, user, enabled):
- manager = keystoneclient(request, admin=True).users
- if VERSIONS.active < 3:
- return manager.update_enabled(user, enabled)
- else:
- return manager.update(user, enabled=enabled)
-
-
-def user_update_password(request, user, password, admin=True):
- manager = keystoneclient(request, admin=admin).users
- if VERSIONS.active < 3:
- return manager.update_password(user, password)
- else:
- return manager.update(user, password=password)
-
-
-def user_update_own_password(request, origpassword, password):
- client = keystoneclient(request, admin=False)
- if VERSIONS.active < 3:
- client.user_id = request.user.id
- return client.users.update_own_password(origpassword, password)
- else:
- return client.users.update(request.user.id, password=password)
-
-
-def user_update_tenant(request, user, project, admin=True):
- manager = keystoneclient(request, admin=admin).users
- if VERSIONS.active < 3:
- return manager.update_tenant(user, project)
- else:
- return manager.update(user, project=project)
-
-
-def group_create(request, domain_id, name, description=None):
- manager = keystoneclient(request, admin=True).groups
- return manager.create(domain=domain_id,
- name=name,
- description=description)
-
-
-def group_get(request, group_id, admin=True):
- manager = keystoneclient(request, admin=admin).groups
- return manager.get(group_id)
-
-
-def group_delete(request, group_id):
- manager = keystoneclient(request, admin=True).groups
- return manager.delete(group_id)
-
-
-def group_list(request):
- manager = keystoneclient(request, admin=True).groups
- return manager.list()
-
-
-def group_update(request, group_id, name=None, description=None):
- manager = keystoneclient(request, admin=True).groups
- return manager.update(group=group_id,
- name=name,
- description=description)
-
-
-def add_group_user(request, group_id, user_id):
- manager = keystoneclient(request, admin=True).users
- return manager.add_to_group(group=group_id, user=user_id)
-
-
-def remove_group_user(request, group_id, user_id):
- manager = keystoneclient(request, admin=True).users
- return manager.remove_from_group(group=group_id, user=user_id)
-
-
-def role_create(request, name):
- manager = keystoneclient(request, admin=True).roles
- return manager.create(name)
-
-
-def role_get(request, role_id):
- manager = keystoneclient(request, admin=True).roles
- return manager.get(role_id)
-
-
-def role_update(request, role_id, name=None):
- manager = keystoneclient(request, admin=True).roles
- return manager.update(role_id, name)
-
-
-def role_delete(request, role_id):
- manager = keystoneclient(request, admin=True).roles
- return manager.delete(role_id)
-
-
-def role_list(request):
- """ Returns a global list of available roles. """
- return keystoneclient(request, admin=True).roles.list()
-
-
-def roles_for_user(request, user, project):
- manager = keystoneclient(request, admin=True).roles
- if VERSIONS.active < 3:
- return manager.roles_for_user(user, project)
- else:
- return manager.list(user=user, project=project)
-
-
-def add_tenant_user_role(request, project=None, user=None, role=None,
- group=None, domain=None):
- """ Adds a role for a user on a tenant. """
- manager = keystoneclient(request, admin=True).roles
- if VERSIONS.active < 3:
- return manager.add_user_role(user, role, project)
- else:
- return manager.grant(role, user=user, project=project,
- group=group, domain=domain)
-
-
-def remove_tenant_user_role(request, project=None, user=None, role=None,
- group=None, domain=None):
- """ Removes a given single role for a user from a tenant. """
- manager = keystoneclient(request, admin=True).roles
- if VERSIONS.active < 3:
- return manager.remove_user_role(user, role, project)
- else:
- return manager.revoke(role, user=user, project=project,
- group=group, domain=domain)
-
-
-def remove_tenant_user(request, project=None, user=None, domain=None):
- """ Removes all roles from a user on a tenant, removing them from it. """
- client = keystoneclient(request, admin=True)
- roles = client.roles.roles_for_user(user, project)
- for role in roles:
- remove_tenant_user_role(request, user=user, role=role.id,
- project=project, domain=domain)
-
-
-def get_default_role(request):
- """
- Gets the default role object from Keystone and saves it as a global
- since this is configured in settings and should not change from request
- to request. Supports lookup by name or id.
- """
- global DEFAULT_ROLE
- default = getattr(settings, "OPENSTACK_KEYSTONE_DEFAULT_ROLE", None)
- if default and DEFAULT_ROLE is None:
- try:
- roles = keystoneclient(request, admin=True).roles.list()
- except:
- roles = []
- exceptions.handle(request)
- for role in roles:
- if role.id == default or role.name == default:
- DEFAULT_ROLE = role
- break
- return DEFAULT_ROLE
-
-
-def list_ec2_credentials(request, user_id):
- return keystoneclient(request).ec2.list(user_id)
-
-
-def create_ec2_credentials(request, user_id, tenant_id):
- return keystoneclient(request).ec2.create(user_id, tenant_id)
-
-
-def get_user_ec2_credentials(request, user_id, access_token):
- return keystoneclient(request).ec2.get(user_id, access_token)
-
-
-def keystone_can_edit_domain():
- backend_settings = getattr(settings, "OPENSTACK_KEYSTONE_BACKEND", {})
- return backend_settings.get('can_edit_domain', True)
-
-
-def keystone_can_edit_user():
- backend_settings = getattr(settings, "OPENSTACK_KEYSTONE_BACKEND", {})
- return backend_settings.get('can_edit_user', True)
-
-
-def keystone_can_edit_project():
- backend_settings = getattr(settings, "OPENSTACK_KEYSTONE_BACKEND", {})
- return backend_settings.get('can_edit_project', True)
-
-
-def keystone_can_edit_group():
- backend_settings = getattr(settings, "OPENSTACK_KEYSTONE_BACKEND", {})
- return backend_settings.get('can_edit_group', True)
-
-
-def keystone_can_edit_role():
- backend_settings = getattr(settings, "OPENSTACK_KEYSTONE_BACKEND", {})
- return backend_settings.get('can_edit_role', True)
-
-
-def keystone_backend_name():
- if hasattr(settings, "OPENSTACK_KEYSTONE_BACKEND"):
- return settings.OPENSTACK_KEYSTONE_BACKEND['name']
- else:
- return 'unknown'
diff --git a/openstack_dashboard/api/lbaas.py b/openstack_dashboard/api/lbaas.py
deleted file mode 100644
index 7958188b..00000000
--- a/openstack_dashboard/api/lbaas.py
+++ /dev/null
@@ -1,321 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013, Big Switch Networks, 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 __future__ import absolute_import
-
-from openstack_dashboard.api.neutron import NeutronAPIDictWrapper
-from openstack_dashboard.api.neutron import neutronclient
-from openstack_dashboard.api.neutron import subnet_get
-
-
-class Vip(NeutronAPIDictWrapper):
- """Wrapper for neutron load balancer vip"""
-
- def __init__(self, apiresource):
- super(Vip, self).__init__(apiresource)
-
-
-class Pool(NeutronAPIDictWrapper):
- """Wrapper for neutron load balancer pool"""
-
- def __init__(self, apiresource):
- super(Pool, self).__init__(apiresource)
-
- class AttributeDict(dict):
- def __getattr__(self, attr):
- return self[attr]
-
- def __setattr__(self, attr, value):
- self[attr] = value
-
- def readable(self, request):
- pFormatted = {'id': self.id,
- 'name': self.name,
- 'description': self.description,
- 'protocol': self.protocol,
- 'health_monitors': self.health_monitors}
- try:
- pFormatted['subnet_id'] = self.subnet_id
- pFormatted['subnet_name'] = subnet_get(
- request, self.subnet_id).cidr
- except:
- pFormatted['subnet_id'] = self.subnet_id
- pFormatted['subnet_name'] = self.subnet_id
-
- if self.vip_id is not None:
- try:
- pFormatted['vip_id'] = self.vip_id
- pFormatted['vip_name'] = vip_get(
- request, self.vip_id).name
- except:
- pFormatted['vip_id'] = self.vip_id
- pFormatted['vip_name'] = self.vip_id
- else:
- pFormatted['vip_id'] = None
- pFormatted['vip_name'] = None
-
- return self.AttributeDict(pFormatted)
-
-
-class Member(NeutronAPIDictWrapper):
- """Wrapper for neutron load balancer member"""
-
- def __init__(self, apiresource):
- super(Member, self).__init__(apiresource)
-
- class AttributeDict(dict):
- def __getattr__(self, attr):
- return self[attr]
-
- def __setattr__(self, attr, value):
- self[attr] = value
-
- def readable(self, request):
- mFormatted = {'id': self.id,
- 'address': self.address,
- 'protocol_port': self.protocol_port}
- try:
- mFormatted['pool_id'] = self.pool_id
- mFormatted['pool_name'] = pool_get(
- request, self.pool_id).name
- except:
- mFormatted['pool_id'] = self.pool_id
- mFormatted['pool_name'] = self.pool_id
-
- return self.AttributeDict(mFormatted)
-
-
-class PoolStats(NeutronAPIDictWrapper):
- """Wrapper for neutron load balancer pool stats"""
-
- def __init__(self, apiresource):
- super(PoolStats, self).__init__(apiresource)
-
-
-class PoolMonitor(NeutronAPIDictWrapper):
- """Wrapper for neutron load balancer pool health monitor"""
-
- def __init__(self, apiresource):
- super(PoolMonitor, self).__init__(apiresource)
-
-
-def vip_create(request, **kwargs):
- """Create a vip for a specified pool.
-
- :param request: request context
- :param address: virtual IP address
- :param name: name for vip
- :param description: description for vip
- :param subnet_id: subnet_id for subnet of vip
- :param protocol_port: transport layer port number for vip
- :returns: Vip object
- """
- body = {'vip': {'address': kwargs['address'],
- 'name': kwargs['name'],
- 'description': kwargs['description'],
- 'subnet_id': kwargs['subnet_id'],
- 'protocol_port': kwargs['protocol_port'],
- 'protocol': kwargs['protocol'],
- 'pool_id': kwargs['pool_id'],
- 'session_persistence': kwargs['session_persistence'],
- 'connection_limit': kwargs['connection_limit'],
- 'admin_state_up': kwargs['admin_state_up']
- }}
- vip = neutronclient(request).create_vip(body).get('vip')
- return Vip(vip)
-
-
-def vips_get(request, **kwargs):
- vips = neutronclient(request).list_vips().get('vips')
- return [Vip(v) for v in vips]
-
-
-def vip_get(request, vip_id):
- vip = neutronclient(request).show_vip(vip_id).get('vip')
- return Vip(vip)
-
-
-def vip_update(request, vip_id, **kwargs):
- vip = neutronclient(request).update_vip(vip_id, kwargs).get('vip')
- return Vip(vip)
-
-
-def vip_delete(request, vip_id):
- neutronclient(request).delete_vip(vip_id)
-
-
-def pool_create(request, **kwargs):
- """Create a pool for specified protocol
-
- :param request: request context
- :param name: name for pool
- :param description: description for pool
- :param subnet_id: subnet_id for subnet of pool
- :param protocol: load balanced protocol
- :param lb_method: load balancer method
- :param admin_state_up: admin state (default on)
- """
- body = {'pool': {'name': kwargs['name'],
- 'description': kwargs['description'],
- 'subnet_id': kwargs['subnet_id'],
- 'protocol': kwargs['protocol'],
- 'lb_method': kwargs['lb_method'],
- 'admin_state_up': kwargs['admin_state_up']
- }}
- pool = neutronclient(request).create_pool(body).get('pool')
- return Pool(pool)
-
-
-def pools_get(request, **kwargs):
- pools = neutronclient(request).list_pools().get('pools')
- return [Pool(p) for p in pools]
-
-
-def pool_get(request, pool_id):
- pool = neutronclient(request).show_pool(pool_id).get('pool')
- return Pool(pool)
-
-
-def pool_update(request, pool_id, **kwargs):
- pool = neutronclient(request).update_pool(pool_id, kwargs).get('pool')
- return Pool(pool)
-
-
-def pool_delete(request, pool):
- neutronclient(request).delete_pool(pool)
-
-
-# not linked to UI yet
-def pool_stats(request, pool_id, **kwargs):
- stats = neutronclient(request).retrieve_pool_stats(pool_id, **kwargs)
- return PoolStats(stats)
-
-
-def pool_health_monitor_create(request, **kwargs):
- """Create a health monitor
-
- :param request: request context
- :param type: type of monitor
- :param delay: delay of monitor
- :param timeout: timeout of monitor
- :param max_retries: max retries [1..10]
- :param http_method: http method
- :param url_path: url path
- :param expected_codes: http return code
- :param admin_state_up: admin state
- """
- monitor_type = kwargs['type'].upper()
- body = {'health_monitor': {'type': monitor_type,
- 'delay': kwargs['delay'],
- 'timeout': kwargs['timeout'],
- 'max_retries': kwargs['max_retries'],
- 'admin_state_up': kwargs['admin_state_up']
- }}
- if monitor_type in ['HTTP', 'HTTPS']:
- body['health_monitor']['http_method'] = kwargs['http_method']
- body['health_monitor']['url_path'] = kwargs['url_path']
- body['health_monitor']['expected_codes'] = kwargs['expected_codes']
- mon = neutronclient(request).create_health_monitor(body).get(
- 'health_monitor')
-
- return PoolMonitor(mon)
-
-
-def pool_health_monitors_get(request, **kwargs):
- monitors = neutronclient(request
- ).list_health_monitors().get('health_monitors')
- return [PoolMonitor(m) for m in monitors]
-
-
-def pool_health_monitor_get(request, monitor_id):
- monitor = neutronclient(request
- ).show_health_monitor(monitor_id
- ).get('health_monitor')
- return PoolMonitor(monitor)
-
-
-def pool_health_monitor_update(request, monitor_id, **kwargs):
- monitor = neutronclient(request).update_health_monitor(monitor_id, kwargs)
- return PoolMonitor(monitor)
-
-
-def pool_health_monitor_delete(request, mon_id):
- neutronclient(request).delete_health_monitor(mon_id)
-
-
-def member_create(request, **kwargs):
- """Create a load balance member
-
- :param request: request context
- :param pool_id: pool_id of pool for member
- :param address: IP address
- :param protocol_port: transport layer port number
- :param weight: weight for member
- :param admin_state_up: admin_state
- """
- body = {'member': {'pool_id': kwargs['pool_id'],
- 'address': kwargs['address'],
- 'protocol_port': kwargs['protocol_port'],
- 'weight': kwargs['weight'],
- 'admin_state_up': kwargs['admin_state_up']
- }}
- member = neutronclient(request).create_member(body).get('member')
- return Member(member)
-
-
-def members_get(request, **kwargs):
- members = neutronclient(request).list_members().get('members')
- return [Member(m) for m in members]
-
-
-def member_get(request, member_id):
- member = neutronclient(request).show_member(member_id).get('member')
- return Member(member)
-
-
-def member_update(request, member_id, **kwargs):
- member = neutronclient(request).update_member(member_id, kwargs)
- return Member(member)
-
-
-def member_delete(request, mem_id):
- neutronclient(request).delete_member(mem_id)
-
-
-def pool_monitor_association_create(request, **kwargs):
- """Associate a health monitor with pool
-
- :param request: request context
- :param monitor_id: id of monitor
- :param pool_id: id of pool
- """
-
- body = {'health_monitor': {'id': kwargs['monitor_id'], }}
-
- neutronclient(request).associate_health_monitor(
- kwargs['pool_id'], body)
-
-
-def pool_monitor_association_delete(request, **kwargs):
- """Disassociate a health monitor from pool
-
- :param request: request context
- :param monitor_id: id of monitor
- :param pool_id: id of pool
- """
-
- neutronclient(request).disassociate_health_monitor(
- kwargs['pool_id'], kwargs['monitor_id'])
diff --git a/openstack_dashboard/api/network.py b/openstack_dashboard/api/network.py
deleted file mode 100644
index b6abbc6d..00000000
--- a/openstack_dashboard/api/network.py
+++ /dev/null
@@ -1,129 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Abstraction layer for networking functionalities.
-
-Currently Nova and Neutron have duplicated features. This API layer is
-introduced to abstract the differences between them for seamless consumption by
-different dashboard implementations.
-"""
-
-from django.conf import settings
-
-from openstack_dashboard.api import base
-from openstack_dashboard.api import neutron
-from openstack_dashboard.api import nova
-
-
-class NetworkClient(object):
- def __init__(self, request):
- neutron_enabled = base.is_service_enabled(request, 'network')
-
- if neutron_enabled:
- self.floating_ips = neutron.FloatingIpManager(request)
- else:
- self.floating_ips = nova.FloatingIpManager(request)
-
- # Not all qunantum plugins support security group,
- # so we have enable_security_group configuration parameter.
- neutron_sg_enabled = getattr(settings,
- 'OPENSTACK_NEUTRON_NETWORK',
- {}).get('enable_security_group', True)
- if neutron_enabled and neutron_sg_enabled:
- self.secgroups = neutron.SecurityGroupManager(request)
- else:
- self.secgroups = nova.SecurityGroupManager(request)
-
-
-def floating_ip_pools_list(request):
- return NetworkClient(request).floating_ips.list_pools()
-
-
-def tenant_floating_ip_list(request):
- return NetworkClient(request).floating_ips.list()
-
-
-def tenant_floating_ip_get(request, floating_ip_id):
- return NetworkClient(request).floating_ips.get(floating_ip_id)
-
-
-def tenant_floating_ip_allocate(request, pool=None):
- return NetworkClient(request).floating_ips.allocate(pool)
-
-
-def tenant_floating_ip_release(request, floating_ip_id):
- return NetworkClient(request).floating_ips.release(floating_ip_id)
-
-
-def floating_ip_associate(request, floating_ip_id, port_id):
- return NetworkClient(request).floating_ips.associate(floating_ip_id,
- port_id)
-
-
-def floating_ip_disassociate(request, floating_ip_id, port_id):
- return NetworkClient(request).floating_ips.disassociate(floating_ip_id,
- port_id)
-
-
-def floating_ip_target_list(request):
- return NetworkClient(request).floating_ips.list_targets()
-
-
-def floating_ip_target_get_by_instance(request, instance_id):
- return NetworkClient(request).floating_ips.get_target_id_by_instance(
- instance_id)
-
-
-def security_group_list(request):
- return NetworkClient(request).secgroups.list()
-
-
-def security_group_get(request, sg_id):
- return NetworkClient(request).secgroups.get(sg_id)
-
-
-def security_group_create(request, name, desc):
- return NetworkClient(request).secgroups.create(name, desc)
-
-
-def security_group_delete(request, sg_id):
- return NetworkClient(request).secgroups.delete(sg_id)
-
-
-def security_group_rule_create(request, parent_group_id,
- direction, ethertype,
- ip_protocol, from_port, to_port,
- cidr, group_id):
- return NetworkClient(request).secgroups.rule_create(
- parent_group_id, direction, ethertype, ip_protocol,
- from_port, to_port, cidr, group_id)
-
-
-def security_group_rule_delete(request, sgr_id):
- return NetworkClient(request).secgroups.rule_delete(sgr_id)
-
-
-def server_security_groups(request, instance_id):
- return NetworkClient(request).secgroups.list_by_instance(instance_id)
-
-
-def server_update_security_groups(request, instance_id, new_sgs):
- return NetworkClient(request).secgroups.update_instance_security_group(
- instance_id, new_sgs)
-
-
-def security_group_backend(request):
- return NetworkClient(request).secgroups.backend
diff --git a/openstack_dashboard/api/network_base.py b/openstack_dashboard/api/network_base.py
deleted file mode 100644
index c2c66b1e..00000000
--- a/openstack_dashboard/api/network_base.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Abstraction layer for networking functionalities.
-
-This module defines internal APIs for duplicated features between OpenStack
-Compute and OpenStack Networking. The networking abstraction layer expects
-methods defined in this module.
-"""
-
-import abc
-
-
-class FloatingIpManager(object):
- """Abstract class to implement Floating IP methods
-
- The FloatingIP object returned from methods in this class
- must contains the following attributes:
-
- * id: ID of Floating IP
- * ip: Floating IP address
- * pool: ID of Floating IP pool from which the address is allocated
- * fixed_ip: Fixed IP address of a VIF associated with the address
- * port_id: ID of a VIF associated with the address
- (instance_id when Nova floating IP is used)
- * instance_id: Instance ID of an associated with the Floating IP
- """
-
- __metaclass__ = abc.ABCMeta
-
- @abc.abstractmethod
- def list_pools(self):
- """Fetches a list of all floating IP pools.
-
- A list of FloatingIpPool objects is returned.
- FloatingIpPool object is an APIResourceWrapper/APIDictWrapper
- where 'id' and 'name' attributes are defined.
- """
- pass
-
- @abc.abstractmethod
- def list(self):
- """Fetches a list all floating IPs.
-
- A returned value is a list of FloatingIp object.
- """
- pass
-
- @abc.abstractmethod
- def get(self, floating_ip_id):
- """Fetches the floating IP.
-
- It returns a FloatingIp object corresponding to floating_ip_id.
- """
- pass
-
- @abc.abstractmethod
- def allocate(self, pool=None):
- """Allocates a floating IP to the tenant.
-
- You must provide a pool name or id for which you would like to
- allocate an floating IP.
- """
- pass
-
- @abc.abstractmethod
- def release(self, floating_ip_id):
- """Releases a floating IP specified."""
- pass
-
- @abc.abstractmethod
- def associate(self, floating_ip_id, port_id):
- """Associates the floating IP to the port.
-
- port_id is a fixed IP of a instance (Nova) or
- a port_id attached to a VNIC of a instance.
- """
- pass
-
- @abc.abstractmethod
- def disassociate(self, floating_ip_id, port_id):
- """Disassociates the floating IP from the port.
-
- port_id is a fixed IP of a instance (Nova) or
- a port_id attached to a VNIC of a instance.
- """
- pass
-
- @abc.abstractmethod
- def list_targets(self):
- """Returns a list of association targets of instance VIFs.
-
- Each association target is represented as FloatingIpTarget object.
- FloatingIpTarget is a APIResourceWrapper/APIDictWrapper and
- 'id' and 'name' attributes must be defined in each object.
- FloatingIpTarget.id can be passed as port_id in associate().
- FloatingIpTarget.name is displayed in Floating Ip Association Form.
- """
- pass
-
- @abc.abstractmethod
- def get_target_id_by_instance(self, instance_id):
- """Returns a target ID of floating IP association based on
- a backend implementation.
- """
- pass
-
- @abc.abstractmethod
- def is_simple_associate_supported(self):
- """Returns True if the default floating IP pool is enabled."""
- pass
-
-
-class SecurityGroupManager(object):
- """Abstract class to implement Security Group methods
-
- SecurityGroup object returned from methods in this class
- must contains the following attributes:
- - id : ID of Security Group (int for Nova, uuid for Neutron)
- - name
- - description
- - tenant_id
- - rules : A list of SecurityGroupRule objects
-
- SecurityGroupRule object should have the following attributes:
- The attribute names and their formats are borrowed from nova
- security group implementation.
- - id
- - direction
- - ethertype
- - parent_group_id : security group the rule belongs to
- - ip_protocol
- - from_port : lower limit of allowed port range (inclusive)
- - to_port : upper limit of allowed port range (inclusive)
- - ip_range : remote IP CIDR (source for ingress, dest for egress)
- The value should be a format of "{'cidr': <cidr>}"
- - group : remote security group
- The value should be a format of "{'name': <secgroup_name>}"
- """
-
- __metaclass__ = abc.ABCMeta
-
- @abc.abstractmethod
- def list(self):
- """Fetches a list all security groups.
-
- A returned value is a list of SecurityGroup object.
- """
- pass
-
- @abc.abstractmethod
- def get(self, sg_id):
- """Fetches the security group.
-
- It returns a SecurityGroup object corresponding to sg_id.
- """
- pass
-
- @abc.abstractmethod
- def create(self, name, desc):
- """Create a new security group.
-
- It returns a SecurityGroup object created.
- """
- pass
-
- @abc.abstractmethod
- def delete(self, sg_id):
- """Delete the specified security group."""
- pass
-
- @abc.abstractmethod
- def rule_create(self, parent_group_id,
- direction=None, ethertype=None,
- ip_protocol=None, from_port=None, to_port=None,
- cidr=None, group_id=None):
- """Create a new security group rule.
-
- :param parent_group_id: security group id a rule is created to
- :param direction: ingress or egress
- :param ethertype: ipv4, ipv6, ...
- :param ip_protocol: tcp, udp, icmp
- :param from_port: L4 port range min
- :param to_port: L4 port range max
- :param cidr: Source IP CIDR
- :param group_id: ID of Source Security Group
- """
- pass
-
- @abc.abstractmethod
- def rule_delete(self, sgr_id):
- """Delete the specified security group rule."""
- pass
-
- @abc.abstractmethod
- def list_by_instance(self, instance_id):
- """Get security groups of an instance."""
- pass
-
- @abc.abstractmethod
- def update_instance_security_group(self, instance_id, new_sgs):
- """Update security groups of a specified instance."""
- pass
diff --git a/openstack_dashboard/api/neutron.py b/openstack_dashboard/api/neutron.py
deleted file mode 100644
index 7060f894..00000000
--- a/openstack_dashboard/api/neutron.py
+++ /dev/null
@@ -1,605 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Cisco Systems, Inc.
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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 __future__ import absolute_import
-
-import logging
-
-from django.conf import settings
-from django.utils.datastructures import SortedDict
-from django.utils.translation import ugettext_lazy as _
-
-from openstack_dashboard.api.base import APIDictWrapper
-from openstack_dashboard.api.base import url_for
-from openstack_dashboard.api import network_base
-from openstack_dashboard.api import nova
-
-from neutronclient.v2_0 import client as neutron_client
-
-LOG = logging.getLogger(__name__)
-
-IP_VERSION_DICT = {4: 'IPv4', 6: 'IPv6'}
-
-
-class NeutronAPIDictWrapper(APIDictWrapper):
-
- def set_id_as_name_if_empty(self, length=8):
- try:
- if not self._apidict['name']:
- id = self._apidict['id']
- if length:
- id = id[:length]
- self._apidict['name'] = '(%s)' % id
- except KeyError:
- pass
-
- def items(self):
- return self._apidict.items()
-
-
-class Network(NeutronAPIDictWrapper):
- """Wrapper for neutron Networks"""
-
- def __init__(self, apiresource):
- apiresource['admin_state'] = \
- 'UP' if apiresource['admin_state_up'] else 'DOWN'
- # Django cannot handle a key name with a colon, so remap another key
- for key in apiresource.keys():
- if key.find(':'):
- apiresource['__'.join(key.split(':'))] = apiresource[key]
- super(Network, self).__init__(apiresource)
-
-
-class Subnet(NeutronAPIDictWrapper):
- """Wrapper for neutron subnets"""
-
- def __init__(self, apiresource):
- apiresource['ipver_str'] = get_ipver_str(apiresource['ip_version'])
- super(Subnet, self).__init__(apiresource)
-
-
-class Port(NeutronAPIDictWrapper):
- """Wrapper for neutron ports"""
-
- def __init__(self, apiresource):
- apiresource['admin_state'] = \
- 'UP' if apiresource['admin_state_up'] else 'DOWN'
- super(Port, self).__init__(apiresource)
-
-
-class Router(NeutronAPIDictWrapper):
- """Wrapper for neutron routers"""
-
- def __init__(self, apiresource):
- #apiresource['admin_state'] = \
- # 'UP' if apiresource['admin_state_up'] else 'DOWN'
- super(Router, self).__init__(apiresource)
-
-
-class SecurityGroup(NeutronAPIDictWrapper):
- # Required attributes: id, name, description, tenant_id, rules
-
- def __init__(self, sg, sg_dict=None):
- if sg_dict is None:
- sg_dict = {sg['id']: sg['name']}
- sg['rules'] = [SecurityGroupRule(rule, sg_dict)
- for rule in sg['security_group_rules']]
- super(SecurityGroup, self).__init__(sg)
-
-
-class SecurityGroupRule(NeutronAPIDictWrapper):
- # Required attributes:
- # id, parent_group_id
- # ip_protocol, from_port, to_port, ip_range, group
- # ethertype, direction (Neutron specific)
-
- def _get_secgroup_name(self, sg_id, sg_dict):
- if sg_id:
- if sg_dict is None:
- sg_dict = {}
- # If sg name not found in sg_dict,
- # first two parts of UUID is used as sg name.
- return sg_dict.get(sg_id, sg_id[:13])
- else:
- return u''
-
- def __init__(self, sgr, sg_dict=None):
- # In Neutron, if both remote_ip_prefix and remote_group_id are None,
- # it means all remote IP range is allowed, i.e., 0.0.0.0/0 or ::/0.
- if not sgr['remote_ip_prefix'] and not sgr['remote_group_id']:
- if sgr['ethertype'] == 'IPv6':
- sgr['remote_ip_prefix'] = '::/0'
- else:
- sgr['remote_ip_prefix'] = '0.0.0.0/0'
-
- rule = {
- 'id': sgr['id'],
- 'parent_group_id': sgr['security_group_id'],
- 'direction': sgr['direction'],
- 'ethertype': sgr['ethertype'],
- 'ip_protocol': sgr['protocol'],
- 'from_port': sgr['port_range_min'],
- 'to_port': sgr['port_range_max'],
- }
- cidr = sgr['remote_ip_prefix']
- rule['ip_range'] = {'cidr': cidr} if cidr else {}
- group = self._get_secgroup_name(sgr['remote_group_id'], sg_dict)
- rule['group'] = {'name': group} if group else {}
- super(SecurityGroupRule, self).__init__(rule)
-
- def __unicode__(self):
- if 'name' in self.group:
- remote = self.group['name']
- elif 'cidr' in self.ip_range:
- remote = self.ip_range['cidr']
- else:
- remote = 'ANY'
- direction = 'to' if self.direction == 'egress' else 'from'
- if self.from_port:
- if self.from_port == self.to_port:
- proto_port = ("%s/%s" %
- (self.from_port, self.ip_protocol.lower()))
- else:
- proto_port = ("%s-%s/%s" %
- (self.from_port, self.to_port,
- self.ip_protocol.lower()))
- elif self.ip_protocol:
- try:
- ip_proto = int(self.ip_protocol)
- proto_port = "ip_proto=%d" % ip_proto
- except:
- # well-defined IP protocol name like TCP, UDP, ICMP.
- proto_port = self.ip_protocol
- else:
- proto_port = ''
-
- return (_('ALLOW %(ethertype)s %(proto_port)s '
- '%(direction)s %(remote)s') %
- {'ethertype': self.ethertype,
- 'proto_port': proto_port,
- 'remote': remote,
- 'direction': direction})
-
-
-class SecurityGroupManager(network_base.SecurityGroupManager):
- backend = 'neutron'
-
- def __init__(self, request):
- self.request = request
- self.client = neutronclient(request)
-
- def _list(self, **filters):
- secgroups = self.client.list_security_groups(**filters)
- return [SecurityGroup(sg) for sg in secgroups.get('security_groups')]
-
- def list(self):
- tenant_id = self.request.user.tenant_id
- return self._list(tenant_id=tenant_id)
-
- def _sg_name_dict(self, sg_id, rules):
- """Create a mapping dict from secgroup id to its name."""
- related_ids = set([sg_id])
- related_ids |= set(filter(None, [r['remote_group_id'] for r in rules]))
- related_sgs = self.client.list_security_groups(id=related_ids,
- fields=['id', 'name'])
- related_sgs = related_sgs.get('security_groups')
- return dict((sg['id'], sg['name']) for sg in related_sgs)
-
- def get(self, sg_id):
- secgroup = self.client.show_security_group(sg_id).get('security_group')
- sg_dict = self._sg_name_dict(sg_id, secgroup['security_group_rules'])
- return SecurityGroup(secgroup, sg_dict)
-
- def create(self, name, desc):
- body = {'security_group': {'name': name,
- 'description': desc}}
- secgroup = self.client.create_security_group(body)
- return SecurityGroup(secgroup.get('security_group'))
-
- def delete(self, sg_id):
- self.client.delete_security_group(sg_id)
-
- def rule_create(self, parent_group_id,
- direction=None, ethertype=None,
- ip_protocol=None, from_port=None, to_port=None,
- cidr=None, group_id=None):
- if not cidr:
- cidr = None
- if from_port < 0:
- from_port = None
- if to_port < 0:
- to_port = None
- if isinstance(ip_protocol, int) and ip_protocol < 0:
- ip_protocol = None
-
- body = {'security_group_rule':
- {'security_group_id': parent_group_id,
- 'direction': direction,
- 'ethertype': ethertype,
- 'protocol': ip_protocol,
- 'port_range_min': from_port,
- 'port_range_max': to_port,
- 'remote_ip_prefix': cidr,
- 'remote_group_id': group_id}}
- rule = self.client.create_security_group_rule(body)
- rule = rule.get('security_group_rule')
- sg_dict = self._sg_name_dict(parent_group_id, [rule])
- return SecurityGroupRule(rule, sg_dict)
-
- def rule_delete(self, sgr_id):
- self.client.delete_security_group_rule(sgr_id)
-
- def list_by_instance(self, instance_id):
- """Gets security groups of an instance."""
- ports = port_list(self.request, device_id=instance_id)
- sg_ids = []
- for p in ports:
- sg_ids += p.security_groups
- return self._list(id=set(sg_ids))
-
- def update_instance_security_group(self, instance_id, new_sgs):
- ports = port_list(self.request, device_id=instance_id)
- for p in ports:
- params = {'security_groups': new_sgs}
- port_modify(self.request, p.id, **params)
-
-
-class FloatingIp(APIDictWrapper):
- _attrs = ['id', 'ip', 'fixed_ip', 'port_id', 'instance_id', 'pool']
-
- def __init__(self, fip):
- fip['ip'] = fip['floating_ip_address']
- fip['fixed_ip'] = fip['fixed_ip_address']
- fip['pool'] = fip['floating_network_id']
- super(FloatingIp, self).__init__(fip)
-
-
-class FloatingIpPool(APIDictWrapper):
- pass
-
-
-class FloatingIpTarget(APIDictWrapper):
- pass
-
-
-class FloatingIpManager(network_base.FloatingIpManager):
- def __init__(self, request):
- self.request = request
- self.client = neutronclient(request)
-
- def list_pools(self):
- search_opts = {'router:external': True}
- return [FloatingIpPool(pool) for pool
- in self.client.list_networks(**search_opts).get('networks')]
-
- def list(self):
- fips = self.client.list_floatingips().get('floatingips')
- # Get port list to add instance_id to floating IP list
- # instance_id is stored in device_id attribute
- ports = port_list(self.request)
- device_id_dict = SortedDict([(p['id'], p['device_id']) for p in ports])
- for fip in fips:
- if fip['port_id']:
- fip['instance_id'] = device_id_dict[fip['port_id']]
- else:
- fip['instance_id'] = None
- return [FloatingIp(fip) for fip in fips]
-
- def get(self, floating_ip_id):
- fip = self.client.show_floatingip(floating_ip_id).get('floatingip')
- if fip['port_id']:
- fip['instance_id'] = port_get(self.request,
- fip['port_id']).device_id
- else:
- fip['instance_id'] = None
- return FloatingIp(fip)
-
- def allocate(self, pool):
- body = {'floatingip': {'floating_network_id': pool}}
- fip = self.client.create_floatingip(body).get('floatingip')
- fip['instance_id'] = None
- return FloatingIp(fip)
-
- def release(self, floating_ip_id):
- self.client.delete_floatingip(floating_ip_id)
-
- def associate(self, floating_ip_id, port_id):
- # NOTE: In Neutron Horizon floating IP support, port_id is
- # "<port_id>_<ip_address>" format to identify multiple ports.
- pid, ip_address = port_id.split('_', 1)
- update_dict = {'port_id': pid,
- 'fixed_ip_address': ip_address}
- self.client.update_floatingip(floating_ip_id,
- {'floatingip': update_dict})
-
- def disassociate(self, floating_ip_id, port_id):
- update_dict = {'port_id': None}
- self.client.update_floatingip(floating_ip_id,
- {'floatingip': update_dict})
-
- def list_targets(self):
- ports = port_list(self.request)
- servers, has_more = nova.server_list(self.request)
- server_dict = SortedDict([(s.id, s.name) for s in servers])
- targets = []
- for p in ports:
- # Remove network ports from Floating IP targets
- if p.device_owner.startswith('network:'):
- continue
- port_id = p.id
- server_name = server_dict.get(p.device_id)
- for ip in p.fixed_ips:
- target = {'name': '%s: %s' % (server_name, ip['ip_address']),
- 'id': '%s_%s' % (port_id, ip['ip_address'])}
- targets.append(FloatingIpTarget(target))
- return targets
-
- def get_target_id_by_instance(self, instance_id):
- # In Neutron one port can have multiple ip addresses, so this method
- # picks up the first one and generate target id.
- if not instance_id:
- return None
- search_opts = {'device_id': instance_id}
- ports = port_list(self.request, **search_opts)
- if not ports:
- return None
- return '%s_%s' % (ports[0].id, ports[0].fixed_ips[0]['ip_address'])
-
- def is_simple_associate_supported(self):
- # NOTE: There are two reason that simple association support
- # needs more considerations. (1) Neutron does not support the
- # default floating IP pool at the moment. It can be avoided
- # in case where only one floating IP pool exists.
- # (2) Neutron floating IP is associated with each VIF and
- # we need to check whether such VIF is only one for an instance
- # to enable simple association support.
- return False
-
-
-def get_ipver_str(ip_version):
- """Convert an ip version number to a human-friendly string"""
- return IP_VERSION_DICT.get(ip_version, '')
-
-
-def neutronclient(request):
- insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
- LOG.debug('neutronclient connection created using token "%s" and url "%s"'
- % (request.user.token.id, url_for(request, 'network')))
- LOG.debug('user_id=%(user)s, tenant_id=%(tenant)s' %
- {'user': request.user.id, 'tenant': request.user.tenant_id})
- c = neutron_client.Client(token=request.user.token.id,
- endpoint_url=url_for(request, 'network'),
- insecure=insecure)
- return c
-
-
-def network_list(request, **params):
- LOG.debug("network_list(): params=%s" % (params))
- networks = neutronclient(request).list_networks(**params).get('networks')
- # Get subnet list to expand subnet info in network list.
- subnets = subnet_list(request)
- subnet_dict = SortedDict([(s['id'], s) for s in subnets])
- # Expand subnet list from subnet_id to values.
- for n in networks:
- n['subnets'] = [subnet_dict.get(s) for s in n.get('subnets', [])]
- return [Network(n) for n in networks]
-
-
-def network_list_for_tenant(request, tenant_id, **params):
- """Return a network list available for the tenant.
- The list contains networks owned by the tenant and public networks.
- If requested_networks specified, it searches requested_networks only.
- """
- LOG.debug("network_list_for_tenant(): tenant_id=%s, params=%s"
- % (tenant_id, params))
-
- # If a user has admin role, network list returned by Neutron API
- # contains networks that do not belong to that tenant.
- # So we need to specify tenant_id when calling network_list().
- networks = network_list(request, tenant_id=tenant_id,
- shared=False, **params)
-
- # In the current Neutron API, there is no way to retrieve
- # both owner networks and public networks in a single API call.
- networks += network_list(request, shared=True, **params)
-
- return networks
-
-
-def network_get(request, network_id, expand_subnet=True, **params):
- LOG.debug("network_get(): netid=%s, params=%s" % (network_id, params))
- network = neutronclient(request).show_network(network_id,
- **params).get('network')
- # Since the number of subnets per network must be small,
- # call subnet_get() for each subnet instead of calling
- # subnet_list() once.
- if expand_subnet:
- network['subnets'] = [subnet_get(request, sid)
- for sid in network['subnets']]
- return Network(network)
-
-
-def network_create(request, **kwargs):
- """
- Create a subnet on a specified network.
- :param request: request context
- :param tenant_id: (optional) tenant id of the network created
- :param name: (optional) name of the network created
- :returns: Subnet object
- """
- LOG.debug("network_create(): kwargs = %s" % kwargs)
- body = {'network': kwargs}
- network = neutronclient(request).create_network(body=body).get('network')
- return Network(network)
-
-
-def network_modify(request, network_id, **kwargs):
- LOG.debug("network_modify(): netid=%s, params=%s" % (network_id, kwargs))
- body = {'network': kwargs}
- network = neutronclient(request).update_network(network_id,
- body=body).get('network')
- return Network(network)
-
-
-def network_delete(request, network_id):
- LOG.debug("network_delete(): netid=%s" % network_id)
- neutronclient(request).delete_network(network_id)
-
-
-def subnet_list(request, **params):
- LOG.debug("subnet_list(): params=%s" % (params))
- subnets = neutronclient(request).list_subnets(**params).get('subnets')
- return [Subnet(s) for s in subnets]
-
-
-def subnet_get(request, subnet_id, **params):
- LOG.debug("subnet_get(): subnetid=%s, params=%s" % (subnet_id, params))
- subnet = neutronclient(request).show_subnet(subnet_id,
- **params).get('subnet')
- return Subnet(subnet)
-
-
-def subnet_create(request, network_id, cidr, ip_version, **kwargs):
- """
- Create a subnet on a specified network.
- :param request: request context
- :param network_id: network id a subnet is created on
- :param cidr: subnet IP address range
- :param ip_version: IP version (4 or 6)
- :param gateway_ip: (optional) IP address of gateway
- :param tenant_id: (optional) tenant id of the subnet created
- :param name: (optional) name of the subnet created
- :returns: Subnet object
- """
- LOG.debug("subnet_create(): netid=%s, cidr=%s, ipver=%d, kwargs=%s"
- % (network_id, cidr, ip_version, kwargs))
- body = {'subnet':
- {'network_id': network_id,
- 'ip_version': ip_version,
- 'cidr': cidr}}
- body['subnet'].update(kwargs)
- subnet = neutronclient(request).create_subnet(body=body).get('subnet')
- return Subnet(subnet)
-
-
-def subnet_modify(request, subnet_id, **kwargs):
- LOG.debug("subnet_modify(): subnetid=%s, kwargs=%s" % (subnet_id, kwargs))
- body = {'subnet': kwargs}
- subnet = neutronclient(request).update_subnet(subnet_id,
- body=body).get('subnet')
- return Subnet(subnet)
-
-
-def subnet_delete(request, subnet_id):
- LOG.debug("subnet_delete(): subnetid=%s" % subnet_id)
- neutronclient(request).delete_subnet(subnet_id)
-
-
-def port_list(request, **params):
- LOG.debug("port_list(): params=%s" % (params))
- ports = neutronclient(request).list_ports(**params).get('ports')
- return [Port(p) for p in ports]
-
-
-def port_get(request, port_id, **params):
- LOG.debug("port_get(): portid=%s, params=%s" % (port_id, params))
- port = neutronclient(request).show_port(port_id, **params).get('port')
- return Port(port)
-
-
-def port_create(request, network_id, **kwargs):
- """
- Create a port on a specified network.
- :param request: request context
- :param network_id: network id a subnet is created on
- :param device_id: (optional) device id attached to the port
- :param tenant_id: (optional) tenant id of the port created
- :param name: (optional) name of the port created
- :returns: Port object
- """
- LOG.debug("port_create(): netid=%s, kwargs=%s" % (network_id, kwargs))
- body = {'port': {'network_id': network_id}}
- body['port'].update(kwargs)
- port = neutronclient(request).create_port(body=body).get('port')
- return Port(port)
-
-
-def port_delete(request, port_id):
- LOG.debug("port_delete(): portid=%s" % port_id)
- neutronclient(request).delete_port(port_id)
-
-
-def port_modify(request, port_id, **kwargs):
- LOG.debug("port_modify(): portid=%s, kwargs=%s" % (port_id, kwargs))
- body = {'port': kwargs}
- port = neutronclient(request).update_port(port_id, body=body).get('port')
- return Port(port)
-
-
-def router_create(request, **kwargs):
- LOG.debug("router_create():, kwargs=%s" % kwargs)
- body = {'router': {}}
- body['router'].update(kwargs)
- router = neutronclient(request).create_router(body=body).get('router')
- return Router(router)
-
-
-def router_get(request, router_id, **params):
- router = neutronclient(request).show_router(router_id,
- **params).get('router')
- return Router(router)
-
-
-def router_list(request, **params):
- routers = neutronclient(request).list_routers(**params).get('routers')
- return [Router(r) for r in routers]
-
-
-def router_delete(request, router_id):
- neutronclient(request).delete_router(router_id)
-
-
-def router_add_interface(request, router_id, subnet_id=None, port_id=None):
- body = {}
- if subnet_id:
- body['subnet_id'] = subnet_id
- if port_id:
- body['port_id'] = port_id
- client = neutronclient(request)
- return client.add_interface_router(router_id, body)
-
-
-def router_remove_interface(request, router_id, subnet_id=None, port_id=None):
- body = {}
- if subnet_id:
- body['subnet_id'] = subnet_id
- if port_id:
- body['port_id'] = port_id
- neutronclient(request).remove_interface_router(router_id, body)
-
-
-def router_add_gateway(request, router_id, network_id):
- body = {'network_id': network_id}
- neutronclient(request).add_gateway_router(router_id, body)
-
-
-def router_remove_gateway(request, router_id):
- neutronclient(request).remove_gateway_router(router_id)
diff --git a/openstack_dashboard/api/nova.py b/openstack_dashboard/api/nova.py
deleted file mode 100644
index ba42c9b0..00000000
--- a/openstack_dashboard/api/nova.py
+++ /dev/null
@@ -1,651 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Openstack, LLC
-# Copyright 2012 Nebula, Inc.
-# Copyright (c) 2012 X.commerce, a business unit of eBay Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from __future__ import absolute_import
-
-import logging
-
-from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
-
-from novaclient.v1_1 import client as nova_client
-from novaclient.v1_1.contrib.list_extensions import ListExtManager
-from novaclient.v1_1 import security_group_rules as nova_rules
-from novaclient.v1_1.security_groups import SecurityGroup as NovaSecurityGroup
-from novaclient.v1_1.servers import REBOOT_HARD
-
-from horizon.conf import HORIZON_CONFIG
-from horizon.utils.memoized import memoized
-
-from openstack_dashboard.api.base import APIDictWrapper
-from openstack_dashboard.api.base import APIResourceWrapper
-from openstack_dashboard.api.base import QuotaSet
-from openstack_dashboard.api.base import url_for
-from openstack_dashboard.api import network_base
-
-
-LOG = logging.getLogger(__name__)
-
-
-# API static values
-INSTANCE_ACTIVE_STATE = 'ACTIVE'
-VOLUME_STATE_AVAILABLE = "available"
-
-
-class VNCConsole(APIDictWrapper):
- """Wrapper for the "console" dictionary returned by the
- novaclient.servers.get_vnc_console method.
- """
- _attrs = ['url', 'type']
-
-
-class SPICEConsole(APIDictWrapper):
- """Wrapper for the "console" dictionary returned by the
- novaclient.servers.get_spice_console method.
- """
- _attrs = ['url', 'type']
-
-
-class Server(APIResourceWrapper):
- """Simple wrapper around novaclient.server.Server
-
- Preserves the request info so image name can later be retrieved
-
- """
- _attrs = ['addresses', 'attrs', 'id', 'image', 'links',
- 'metadata', 'name', 'private_ip', 'public_ip', 'status', 'uuid',
- 'image_name', 'VirtualInterfaces', 'flavor', 'key_name',
- 'tenant_id', 'user_id', 'OS-EXT-STS:power_state',
- 'OS-EXT-STS:task_state', 'OS-EXT-SRV-ATTR:instance_name',
- 'OS-EXT-SRV-ATTR:host', 'created']
-
- def __init__(self, apiresource, request):
- super(Server, self).__init__(apiresource)
- self.request = request
-
- @property
- def image_name(self):
- import glanceclient.exc as glance_exceptions
- from openstack_dashboard.api import glance
- if not self.image:
- return "(not found)"
- try:
- image = glance.image_get(self.request, self.image['id'])
- return image.name
- except glance_exceptions.ClientException:
- return "(not found)"
-
- @property
- def internal_name(self):
- return getattr(self, 'OS-EXT-SRV-ATTR:instance_name', "")
-
- def reboot(self, hardness=REBOOT_HARD):
- novaclient(self.request).servers.reboot(self.id, hardness)
-
-
-class NovaUsage(APIResourceWrapper):
- """Simple wrapper around contrib/simple_usage.py."""
- _attrs = ['start', 'server_usages', 'stop', 'tenant_id',
- 'total_local_gb_usage', 'total_memory_mb_usage',
- 'total_vcpus_usage', 'total_hours']
-
- def get_summary(self):
- return {'instances': self.total_active_instances,
- 'memory_mb': self.memory_mb,
- 'vcpus': getattr(self, "total_vcpus_usage", 0),
- 'vcpu_hours': self.vcpu_hours,
- 'local_gb': self.local_gb,
- 'disk_gb_hours': self.disk_gb_hours}
-
- @property
- def total_active_instances(self):
- return sum(1 for s in self.server_usages if s['ended_at'] is None)
-
- @property
- def vcpus(self):
- return sum(s['vcpus'] for s in self.server_usages
- if s['ended_at'] is None)
-
- @property
- def vcpu_hours(self):
- return getattr(self, "total_hours", 0)
-
- @property
- def local_gb(self):
- return sum(s['local_gb'] for s in self.server_usages
- if s['ended_at'] is None)
-
- @property
- def memory_mb(self):
- return sum(s['memory_mb'] for s in self.server_usages
- if s['ended_at'] is None)
-
- @property
- def disk_gb_hours(self):
- return getattr(self, "total_local_gb_usage", 0)
-
-
-class SecurityGroup(APIResourceWrapper):
- """Wrapper around novaclient.security_groups.SecurityGroup which wraps its
- rules in SecurityGroupRule objects and allows access to them.
- """
- _attrs = ['id', 'name', 'description', 'tenant_id']
-
- @property
- def rules(self):
- """Wraps transmitted rule info in the novaclient rule class."""
- if "_rules" not in self.__dict__:
- manager = nova_rules.SecurityGroupRuleManager(None)
- rule_objs = [nova_rules.SecurityGroupRule(manager, rule)
- for rule in self._apiresource.rules]
- self._rules = [SecurityGroupRule(rule) for rule in rule_objs]
- return self.__dict__['_rules']
-
-
-class SecurityGroupRule(APIResourceWrapper):
- """ Wrapper for individual rules in a SecurityGroup. """
- _attrs = ['id', 'ip_protocol', 'from_port', 'to_port', 'ip_range', 'group']
-
- def __unicode__(self):
- if 'name' in self.group:
- vals = {'from': self.from_port,
- 'to': self.to_port,
- 'group': self.group['name']}
- return _('ALLOW %(from)s:%(to)s from %(group)s') % vals
- else:
- vals = {'from': self.from_port,
- 'to': self.to_port,
- 'cidr': self.ip_range['cidr']}
- return _('ALLOW %(from)s:%(to)s from %(cidr)s') % vals
-
- # The following attributes are defined to keep compatibility with Neutron
- @property
- def ethertype(self):
- return None
-
- @property
- def direction(self):
- return 'ingress'
-
-
-class SecurityGroupManager(network_base.SecurityGroupManager):
- backend = 'nova'
-
- def __init__(self, request):
- self.request = request
- self.client = novaclient(request)
-
- def list(self):
- return [SecurityGroup(g) for g
- in self.client.security_groups.list()]
-
- def get(self, sg_id):
- return SecurityGroup(self.client.security_groups.get(sg_id))
-
- def create(self, name, desc):
- return SecurityGroup(self.client.security_groups.create(name, desc))
-
- def delete(self, security_group_id):
- self.client.security_groups.delete(security_group_id)
-
- def rule_create(self, parent_group_id,
- direction=None, ethertype=None,
- ip_protocol=None, from_port=None, to_port=None,
- cidr=None, group_id=None):
- # Nova Security Group API does not use direction and ethertype fields.
- sg = self.client.security_group_rules.create(parent_group_id,
- ip_protocol,
- from_port,
- to_port,
- cidr,
- group_id)
- return SecurityGroupRule(sg)
-
- def rule_delete(self, security_group_rule_id):
- self.client.security_group_rules.delete(security_group_rule_id)
-
- def list_by_instance(self, instance_id):
- """Gets security groups of an instance."""
- # TODO(gabriel): This needs to be moved up to novaclient, and should
- # be removed once novaclient supports this call.
- security_groups = []
- nclient = self.client
- resp, body = nclient.client.get('/servers/%s/os-security-groups'
- % instance_id)
- if body:
- # Wrap data in SG objects as novaclient would.
- sg_objs = [NovaSecurityGroup(nclient.security_groups, sg,
- loaded=True)
- for sg in body.get('security_groups', [])]
- # Then wrap novaclient's object with our own. Yes, sadly wrapping
- # with two layers of objects is necessary.
- security_groups = [SecurityGroup(sg) for sg in sg_objs]
- return security_groups
-
- def update_instance_security_group(self, instance_id, new_sgs):
-
- wanted_groups = set(new_sgs)
- try:
- current_groups = self.list_by_instance(instance_id)
- except Exception:
- raise Exception(_("Couldn't get current security group "
- "list for instance %s.")
- % instance_id)
-
- current_group_names = set(map(lambda g: g.id, current_groups))
- groups_to_add = wanted_groups - current_group_names
- groups_to_remove = current_group_names - wanted_groups
-
- num_groups_to_modify = len(groups_to_add | groups_to_remove)
- try:
- for group in groups_to_add:
- self.client.servers.add_security_group(instance_id, group)
- num_groups_to_modify -= 1
- for group in groups_to_remove:
- self.client.servers.remove_security_group(instance_id, group)
- num_groups_to_modify -= 1
- except Exception:
- raise Exception(_('Failed to modify %d instance security groups.')
- % num_groups_to_modify)
- return True
-
-
-class FlavorExtraSpec(object):
- def __init__(self, flavor_id, key, val):
- self.flavor_id = flavor_id
- self.id = key
- self.key = key
- self.value = val
-
-
-class FloatingIp(APIResourceWrapper):
- _attrs = ['id', 'ip', 'fixed_ip', 'port_id', 'instance_id', 'pool']
-
- def __init__(self, fip):
- fip.__setattr__('port_id', fip.instance_id)
- super(FloatingIp, self).__init__(fip)
-
-
-class FloatingIpPool(APIDictWrapper):
- def __init__(self, pool):
- pool_dict = {'id': pool.name,
- 'name': pool.name}
- super(FloatingIpPool, self).__init__(pool_dict)
-
-
-class FloatingIpTarget(APIDictWrapper):
- def __init__(self, server):
- server_dict = {'name': '%s (%s)' % (server.name, server.id),
- 'id': server.id}
- super(FloatingIpTarget, self).__init__(server_dict)
-
-
-class FloatingIpManager(network_base.FloatingIpManager):
- def __init__(self, request):
- self.request = request
- self.client = novaclient(request)
-
- def list_pools(self):
- return [FloatingIpPool(pool)
- for pool in self.client.floating_ip_pools.list()]
-
- def list(self):
- return [FloatingIp(fip)
- for fip in self.client.floating_ips.list()]
-
- def get(self, floating_ip_id):
- return FloatingIp(self.client.floating_ips.get(floating_ip_id))
-
- def allocate(self, pool):
- return FloatingIp(self.client.floating_ips.create(pool=pool))
-
- def release(self, floating_ip_id):
- self.client.floating_ips.delete(floating_ip_id)
-
- def associate(self, floating_ip_id, port_id):
- # In Nova implied port_id is instance_id
- server = self.client.servers.get(port_id)
- fip = self.client.floating_ips.get(floating_ip_id)
- self.client.servers.add_floating_ip(server.id, fip.ip)
-
- def disassociate(self, floating_ip_id, port_id):
- fip = self.client.floating_ips.get(floating_ip_id)
- server = self.client.servers.get(fip.instance_id)
- self.client.servers.remove_floating_ip(server.id, fip.ip)
-
- def list_targets(self):
- return [FloatingIpTarget(s) for s in self.client.servers.list()]
-
- def get_target_id_by_instance(self, instance_id):
- return instance_id
-
- def is_simple_associate_supported(self):
- return HORIZON_CONFIG["simple_ip_management"]
-
-
-def novaclient(request):
- insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
- LOG.debug('novaclient connection created using token "%s" and url "%s"' %
- (request.user.token.id, url_for(request, 'compute')))
- c = nova_client.Client(request.user.username,
- request.user.token.id,
- project_id=request.user.tenant_id,
- auth_url=url_for(request, 'compute'),
- insecure=insecure,
- http_log_debug=settings.DEBUG)
- c.client.auth_token = request.user.token.id
- c.client.management_url = url_for(request, 'compute')
- return c
-
-
-def server_vnc_console(request, instance_id, console_type='novnc'):
- return VNCConsole(novaclient(request).servers.get_vnc_console(instance_id,
- console_type)['console'])
-
-
-def server_spice_console(request, instance_id, console_type='spice-html5'):
- return SPICEConsole(novaclient(request).servers.get_spice_console(
- instance_id, console_type)['console'])
-
-
-def flavor_create(request, name, memory, vcpu, disk, flavorid='auto',
- ephemeral=0, swap=0, metadata=None):
- flavor = novaclient(request).flavors.create(name, memory, vcpu, disk,
- flavorid=flavorid,
- ephemeral=ephemeral,
- swap=swap)
- if (metadata):
- flavor_extra_set(request, flavor.id, metadata)
- return flavor
-
-
-def flavor_delete(request, flavor_id):
- novaclient(request).flavors.delete(flavor_id)
-
-
-def flavor_get(request, flavor_id):
- return novaclient(request).flavors.get(flavor_id)
-
-
-@memoized
-def flavor_list(request):
- """Get the list of available instance sizes (flavors)."""
- return novaclient(request).flavors.list()
-
-
-def flavor_get_extras(request, flavor_id, raw=False):
- """Get flavor extra specs."""
- flavor = novaclient(request).flavors.get(flavor_id)
- extras = flavor.get_keys()
- if raw:
- return extras
- return [FlavorExtraSpec(flavor_id, key, value) for
- key, value in extras.items()]
-
-
-def flavor_extra_delete(request, flavor_id, keys):
- """Unset the flavor extra spec keys."""
- flavor = novaclient(request).flavors.get(flavor_id)
- return flavor.unset_keys(keys)
-
-
-def flavor_extra_set(request, flavor_id, metadata):
- """Set the flavor extra spec keys."""
- flavor = novaclient(request).flavors.get(flavor_id)
- if (not metadata): # not a way to delete keys
- return None
- return flavor.set_keys(metadata)
-
-
-def snapshot_create(request, instance_id, name):
- return novaclient(request).servers.create_image(instance_id, name)
-
-
-def keypair_create(request, name):
- return novaclient(request).keypairs.create(name)
-
-
-def keypair_import(request, name, public_key):
- return novaclient(request).keypairs.create(name, public_key)
-
-
-def keypair_delete(request, keypair_id):
- novaclient(request).keypairs.delete(keypair_id)
-
-
-def keypair_list(request):
- return novaclient(request).keypairs.list()
-
-
-def server_create(request, name, image, flavor, key_name, user_data,
- security_groups, block_device_mapping, nics=None,
- availability_zone=None, instance_count=1, admin_pass=None):
- return Server(novaclient(request).servers.create(
- name, image, flavor, userdata=user_data,
- security_groups=security_groups,
- key_name=key_name, block_device_mapping=block_device_mapping,
- nics=nics, availability_zone=availability_zone,
- min_count=instance_count, admin_pass=admin_pass), request)
-
-
-def server_delete(request, instance):
- novaclient(request).servers.delete(instance)
-
-
-def server_get(request, instance_id):
- return Server(novaclient(request).servers.get(instance_id), request)
-
-
-def server_list(request, search_opts=None, all_tenants=False):
- page_size = request.session.get('horizon_pagesize',
- getattr(settings, 'API_RESULT_PAGE_SIZE',
- 20))
- paginate = False
- if search_opts is None:
- search_opts = {}
- elif 'paginate' in search_opts:
- paginate = search_opts.pop('paginate')
- if paginate:
- search_opts['limit'] = page_size + 1
-
- if all_tenants:
- search_opts['all_tenants'] = True
- else:
- search_opts['project_id'] = request.user.tenant_id
- servers = [Server(s, request)
- for s in novaclient(request).servers.list(True, search_opts)]
-
- has_more_data = False
- if paginate and len(servers) > page_size:
- servers.pop(-1)
- has_more_data = True
- elif paginate and len(servers) == getattr(settings, 'API_RESULT_LIMIT',
- 1000):
- has_more_data = True
- return (servers, has_more_data)
-
-
-def server_console_output(request, instance_id, tail_length=None):
- """Gets console output of an instance."""
- return novaclient(request).servers.get_console_output(instance_id,
- length=tail_length)
-
-
-def server_pause(request, instance_id):
- novaclient(request).servers.pause(instance_id)
-
-
-def server_unpause(request, instance_id):
- novaclient(request).servers.unpause(instance_id)
-
-
-def server_suspend(request, instance_id):
- novaclient(request).servers.suspend(instance_id)
-
-
-def server_resume(request, instance_id):
- novaclient(request).servers.resume(instance_id)
-
-
-def server_reboot(request, instance_id, hardness=REBOOT_HARD):
- server = server_get(request, instance_id)
- server.reboot(hardness)
-
-
-def server_update(request, instance_id, name):
- response = novaclient(request).servers.update(instance_id, name=name)
- # TODO(gabriel): servers.update method doesn't return anything. :-(
- if response is None:
- return True
- else:
- return response
-
-
-def server_migrate(request, instance_id):
- novaclient(request).servers.migrate(instance_id)
-
-
-def server_resize(request, instance_id, flavor, **kwargs):
- novaclient(request).servers.resize(instance_id, flavor, **kwargs)
-
-
-def server_confirm_resize(request, instance_id):
- novaclient(request).servers.confirm_resize(instance_id)
-
-
-def server_revert_resize(request, instance_id):
- novaclient(request).servers.revert_resize(instance_id)
-
-
-def server_start(request, instance_id):
- novaclient(request).servers.start(instance_id)
-
-
-def server_stop(request, instance_id):
- novaclient(request).servers.stop(instance_id)
-
-
-def tenant_quota_get(request, tenant_id):
- return QuotaSet(novaclient(request).quotas.get(tenant_id))
-
-
-def tenant_quota_update(request, tenant_id, **kwargs):
- novaclient(request).quotas.update(tenant_id, **kwargs)
-
-
-def default_quota_get(request, tenant_id):
- return QuotaSet(novaclient(request).quotas.defaults(tenant_id))
-
-
-def usage_get(request, tenant_id, start, end):
- return NovaUsage(novaclient(request).usage.get(tenant_id, start, end))
-
-
-def usage_list(request, start, end):
- return [NovaUsage(u) for u in
- novaclient(request).usage.list(start, end, True)]
-
-
-def virtual_interfaces_list(request, instance_id):
- return novaclient(request).virtual_interfaces.list(instance_id)
-
-
-def get_x509_credentials(request):
- return novaclient(request).certs.create()
-
-
-def get_x509_root_certificate(request):
- return novaclient(request).certs.get()
-
-
-def instance_volume_attach(request, volume_id, instance_id, device):
- return novaclient(request).volumes.create_server_volume(instance_id,
- volume_id,
- device)
-
-
-def instance_volume_detach(request, instance_id, att_id):
- return novaclient(request).volumes.delete_server_volume(instance_id,
- att_id)
-
-
-def instance_volumes_list(request, instance_id):
- from openstack_dashboard.api.cinder import cinderclient
-
- volumes = novaclient(request).volumes.get_server_volumes(instance_id)
-
- for volume in volumes:
- volume_data = cinderclient(request).volumes.get(volume.id)
- volume.name = volume_data.display_name
-
- return volumes
-
-
-def hypervisor_list(request):
- return novaclient(request).hypervisors.list()
-
-
-def tenant_absolute_limits(request, reserved=False):
- limits = novaclient(request).limits.get(reserved=reserved).absolute
- limits_dict = {}
- for limit in limits:
- # -1 is used to represent unlimited quotas
- if limit.value == -1:
- limits_dict[limit.name] = float("inf")
- else:
- limits_dict[limit.name] = limit.value
- return limits_dict
-
-
-def availability_zone_list(request, detailed=False):
- return novaclient(request).availability_zones.list(detailed=detailed)
-
-
-def service_list(request):
- return novaclient(request).services.list()
-
-
-def aggregate_list(request):
- result = []
- for aggregate in novaclient(request).aggregates.list():
- result.append(novaclient(request).aggregates.get(aggregate.id))
-
- return result
-
-
-@memoized
-def list_extensions(request):
- return ListExtManager(novaclient(request)).show_all()
-
-
-@memoized
-def extension_supported(extension_name, request):
- """
- this method will determine if nova supports a given extension name.
- example values for the extension_name include AdminActions, ConsoleOutput,
- etc.
- """
- extensions = list_extensions(request)
- for extension in extensions:
- if extension.name == extension_name:
- return True
- return False
diff --git a/openstack_dashboard/api/swift.py b/openstack_dashboard/api/swift.py
deleted file mode 100644
index f13ddc42..00000000
--- a/openstack_dashboard/api/swift.py
+++ /dev/null
@@ -1,241 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-import swiftclient
-
-from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import messages
-
-from openstack_dashboard.api.base import APIDictWrapper
-from openstack_dashboard.api.base import url_for
-
-
-LOG = logging.getLogger(__name__)
-FOLDER_DELIMITER = "/"
-
-
-class Container(APIDictWrapper):
- pass
-
-
-class StorageObject(APIDictWrapper):
- def __init__(self, apidict, container_name, orig_name=None, data=None):
- super(StorageObject, self).__init__(apidict)
- self.container_name = container_name
- self.orig_name = orig_name
- self.data = data
-
- @property
- def id(self):
- return self.name
-
-
-class PseudoFolder(APIDictWrapper):
- def __init__(self, apidict, container_name):
- super(PseudoFolder, self).__init__(apidict)
- self.container_name = container_name
-
- @property
- def id(self):
- return '%s/%s' % (self.container_name, self.name)
-
- @property
- def name(self):
- return self.subdir.rstrip(FOLDER_DELIMITER)
-
- @property
- def bytes(self):
- return None
-
- @property
- def content_type(self):
- return "application/pseudo-folder"
-
-
-def _objectify(items, container_name):
- """ Splits a listing of objects into their appropriate wrapper classes. """
- objects = []
-
- # Deal with objects and object pseudo-folders first, save subdirs for later
- for item in items:
- if item.get("subdir", None) is not None:
- object_cls = PseudoFolder
- else:
- object_cls = StorageObject
-
- objects.append(object_cls(item, container_name))
-
- return objects
-
-
-def swift_api(request):
- endpoint = url_for(request, 'object-store')
- LOG.debug('Swift connection created using token "%s" and url "%s"'
- % (request.user.token.id, endpoint))
- return swiftclient.client.Connection(None,
- request.user.username,
- None,
- preauthtoken=request.user.token.id,
- preauthurl=endpoint,
- auth_version="2.0")
-
-
-def swift_container_exists(request, container_name):
- try:
- swift_api(request).head_container(container_name)
- return True
- except swiftclient.client.ClientException:
- return False
-
-
-def swift_object_exists(request, container_name, object_name):
- try:
- swift_api(request).head_object(container_name, object_name)
- return True
- except swiftclient.client.ClientException:
- return False
-
-
-def swift_get_containers(request, marker=None):
- limit = getattr(settings, 'API_RESULT_LIMIT', 1000)
- headers, containers = swift_api(request).get_account(limit=limit + 1,
- marker=marker,
- full_listing=True)
- container_objs = [Container(c) for c in containers]
- if(len(container_objs) > limit):
- return (container_objs[0:-1], True)
- else:
- return (container_objs, False)
-
-
-def swift_create_container(request, name):
- if swift_container_exists(request, name):
- raise exceptions.AlreadyExists(name, 'container')
- swift_api(request).put_container(name)
- return Container({'name': name})
-
-
-def swift_delete_container(request, name):
- # It cannot be deleted if it's not empty. The batch remove of objects
- # be done in swiftclient instead of Horizon.
- objects, more = swift_get_objects(request, name)
- if objects:
- messages.warning(request,
- _("The container cannot be deleted since it's not empty."))
- return False
- swift_api(request).delete_container(name)
- return True
-
-
-def swift_get_objects(request, container_name, prefix=None, marker=None,
- limit=None):
- limit = limit or getattr(settings, 'API_RESULT_LIMIT', 1000)
- kwargs = dict(prefix=prefix,
- marker=marker,
- limit=limit + 1,
- delimiter=FOLDER_DELIMITER,
- full_listing=True)
- headers, objects = swift_api(request).get_container(container_name,
- **kwargs)
- object_objs = _objectify(objects, container_name)
-
- if(len(object_objs) > limit):
- return (object_objs[0:-1], True)
- else:
- return (object_objs, False)
-
-
-def swift_filter_objects(request, filter_string, container_name, prefix=None,
- marker=None):
- # FIXME(kewu): Swift currently has no real filtering API, thus the marker
- # parameter here won't actually help the pagination. For now I am just
- # getting the largest number of objects from a container and filtering
- # based on those objects.
- limit = 9999
- objects = swift_get_objects(request,
- container_name,
- prefix=prefix,
- marker=marker,
- limit=limit)
- filter_string_list = filter_string.lower().strip().split(' ')
-
- def matches_filter(obj):
- for q in filter_string_list:
- return wildcard_search(obj.name.lower(), q)
-
- return filter(matches_filter, objects[0])
-
-
-def wildcard_search(string, q):
- q_list = q.split('*')
- if all(map(lambda x: x == '', q_list)):
- return True
- elif q_list[0] not in string:
- return False
- else:
- if q_list[0] == '':
- tail = string
- else:
- head, delimiter, tail = string.partition(q_list[0])
- return wildcard_search(tail, '*'.join(q_list[1:]))
-
-
-def swift_copy_object(request, orig_container_name, orig_object_name,
- new_container_name, new_object_name):
- if swift_object_exists(request, new_container_name, new_object_name):
- raise exceptions.AlreadyExists(new_object_name, 'object')
-
- headers = {"X-Copy-From": FOLDER_DELIMITER.join([orig_container_name,
- orig_object_name])}
- return swift_api(request).put_object(new_container_name,
- new_object_name,
- None,
- headers=headers)
-
-
-def swift_upload_object(request, container_name, object_name, object_file):
- headers = {}
- headers['X-Object-Meta-Orig-Filename'] = object_file.name
- etag = swift_api(request).put_object(container_name,
- object_name,
- object_file,
- headers=headers)
- obj_info = {'name': object_name, 'bytes': object_file.size, 'etag': etag}
- return StorageObject(obj_info, container_name)
-
-
-def swift_delete_object(request, container_name, object_name):
- swift_api(request).delete_object(container_name, object_name)
- return True
-
-
-def swift_get_object(request, container_name, object_name):
- headers, data = swift_api(request).get_object(container_name, object_name)
- orig_name = headers.get("x-object-meta-orig-filename")
- obj_info = {'name': object_name, 'bytes': len(data)}
- return StorageObject(obj_info,
- container_name,
- orig_name=orig_name,
- data=data)
diff --git a/openstack_dashboard/context_processors.py b/openstack_dashboard/context_processors.py
deleted file mode 100644
index 4d715f36..00000000
--- a/openstack_dashboard/context_processors.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-"""
-Context processors used by Horizon.
-"""
-
-import logging
-
-from django.conf import settings
-
-
-LOG = logging.getLogger(__name__)
-
-
-def openstack(request):
- """ Context processor necessary for OpenStack Dashboard functionality.
-
- The following variables are added to the request context:
-
- ``authorized_tenants``
- A list of tenant objects which the current user has access to.
-
- ``regions``
-
- A dictionary containing information about region support, the current
- region, and available regions.
- """
- context = {}
-
- # Auth/Keystone context
- context.setdefault('authorized_tenants', [])
- current_dash = request.horizon['dashboard']
- needs_tenants = getattr(current_dash, 'supports_tenants', False)
- if request.user.is_authenticated() and needs_tenants:
- context['authorized_tenants'] = request.user.authorized_tenants
-
- # Region context/support
- available_regions = getattr(settings, 'AVAILABLE_REGIONS', [])
- regions = {'support': len(available_regions) > 1,
- 'current': {'endpoint': request.session.get('region_endpoint'),
- 'name': request.session.get('region_name')},
- 'available': [{'endpoint': region[0], 'name':region[1]} for
- region in available_regions]}
- context['regions'] = regions
-
- return context
diff --git a/openstack_dashboard/dashboards/__init__.py b/openstack_dashboard/dashboards/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/__init__.py b/openstack_dashboard/dashboards/admin/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/aggregates/__init__.py b/openstack_dashboard/dashboards/admin/aggregates/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/aggregates/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/aggregates/panel.py b/openstack_dashboard/dashboards/admin/aggregates/panel.py
deleted file mode 100644
index a95f83ed..00000000
--- a/openstack_dashboard/dashboards/admin/aggregates/panel.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 B1 Systems GmbH
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.dashboards.admin import dashboard
-
-
-class Aggregates(horizon.Panel):
- name = _("Aggregates")
- slug = 'aggregates'
- permissions = ('openstack.roles.admin',)
-
-
-dashboard.Admin.register(Aggregates)
diff --git a/openstack_dashboard/dashboards/admin/aggregates/tables.py b/openstack_dashboard/dashboards/admin/aggregates/tables.py
deleted file mode 100644
index 378e1a18..00000000
--- a/openstack_dashboard/dashboards/admin/aggregates/tables.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 B1 Systems GmbH
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django import template
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-LOG = logging.getLogger(__name__)
-
-
-def get_hosts(aggregate):
- template_name = 'admin/aggregates/_aggregate_hosts.html'
- context = {"aggregate": aggregate}
- return template.loader.render_to_string(template_name, context)
-
-
-def get_metadata(aggregate):
- template_name = 'admin/aggregates/_aggregate_metadata.html'
- context = {"aggregate": aggregate}
- return template.loader.render_to_string(template_name, context)
-
-
-class AdminAggregatesTable(tables.DataTable):
- name = tables.Column("name",
- verbose_name=_("Name"))
-
- availability_zone = tables.Column("availability_zone",
- verbose_name=_("Availability Zone"))
-
- hosts = tables.Column(get_hosts,
- verbose_name=_("Hosts"))
-
- metadata = tables.Column(get_metadata,
- verbose_name=_("Metadata"))
-
- class Meta:
- name = "aggregates"
- verbose_name = _("Aggregates")
diff --git a/openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/_aggregate_hosts.html b/openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/_aggregate_hosts.html
deleted file mode 100644
index c85c3e90..00000000
--- a/openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/_aggregate_hosts.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<ul>
-{% for host in aggregate.hosts %}
- <li>{{ host }}</li>
-{% endfor %}
-</ul>
diff --git a/openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/_aggregate_metadata.html b/openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/_aggregate_metadata.html
deleted file mode 100644
index ab8be7c3..00000000
--- a/openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/_aggregate_metadata.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<ul>
-{% for key, value in aggregate.metadata.iteritems %}
- <li>{{ key }} = {{ value }}</li>
-{% endfor %}
-</ul>
diff --git a/openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/index.html b/openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/index.html
deleted file mode 100644
index 42b7cab7..00000000
--- a/openstack_dashboard/dashboards/admin/aggregates/templates/aggregates/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Aggregates" %}{% endblock %}
-
-{% block page_header %}
-{% include "horizon/common/_page_header.html" with title=_("All Aggregates") %}
-{% endblock page_header %}
-
-{% block main %}
-{{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/aggregates/tests.py b/openstack_dashboard/dashboards/admin/aggregates/tests.py
deleted file mode 100644
index babcd735..00000000
--- a/openstack_dashboard/dashboards/admin/aggregates/tests.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 B1 Systems GmbH
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.core.urlresolvers import reverse
-from django import http
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class AggregateViewTest(test.BaseAdminViewTests):
- @test.create_stubs({api.nova: ('aggregate_list',)})
- def test_index(self):
- aggregates = self.aggregates.list()
- api.nova.aggregate_list(IsA(http.HttpRequest)).AndReturn(aggregates)
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:aggregates:index'))
- self.assertTemplateUsed(res, 'admin/aggregates/index.html')
- self.assertItemsEqual(res.context['table'].data, aggregates)
diff --git a/openstack_dashboard/dashboards/admin/aggregates/urls.py b/openstack_dashboard/dashboards/admin/aggregates/urls.py
deleted file mode 100644
index f8649a2f..00000000
--- a/openstack_dashboard/dashboards/admin/aggregates/urls.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 B1 Systems GmbH
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.aggregates.views \
- import AdminIndexView
-
-
-urlpatterns = patterns(
- 'openstack_dashboard.dashboards.admin.aggregates.views',
- url(r'^$', AdminIndexView.as_view(), name='index')
-)
diff --git a/openstack_dashboard/dashboards/admin/aggregates/views.py b/openstack_dashboard/dashboards/admin/aggregates/views.py
deleted file mode 100644
index 31cf3767..00000000
--- a/openstack_dashboard/dashboards/admin/aggregates/views.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 B1 Systems GmbH
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.admin.aggregates.tables import \
- AdminAggregatesTable
-
-LOG = logging.getLogger(__name__)
-
-
-class AdminIndexView(tables.DataTableView):
- table_class = AdminAggregatesTable
- template_name = 'admin/aggregates/index.html'
-
- def get_data(self):
- aggregates = []
- try:
- aggregates = api.nova.aggregate_list(self.request)
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve aggregate list.'))
-
- return aggregates
diff --git a/openstack_dashboard/dashboards/admin/dashboard.py b/openstack_dashboard/dashboards/admin/dashboard.py
deleted file mode 100644
index 9291aea5..00000000
--- a/openstack_dashboard/dashboards/admin/dashboard.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-
-class SystemPanels(horizon.PanelGroup):
- slug = "admin"
- name = _("System Panel")
- panels = ('overview', 'aggregates', 'hypervisors', 'instances', 'volumes',
- 'flavors', 'images', 'networks', 'routers', 'info')
-
-
-class IdentityPanels(horizon.PanelGroup):
- slug = "identity"
- name = _("Identity Panel")
- panels = ('domains', 'projects', 'users', 'groups', 'roles')
-
-
-class Admin(horizon.Dashboard):
- name = _("Admin")
- slug = "admin"
- panels = (SystemPanels, IdentityPanels)
- default_panel = 'overview'
- permissions = ('openstack.roles.admin',)
-
-
-horizon.register(Admin)
diff --git a/openstack_dashboard/dashboards/admin/domains/__init__.py b/openstack_dashboard/dashboards/admin/domains/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/domains/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/domains/constants.py b/openstack_dashboard/dashboards/admin/domains/constants.py
deleted file mode 100644
index e871ace2..00000000
--- a/openstack_dashboard/dashboards/admin/domains/constants.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-DOMAIN_INFO_FIELDS = ("name",
- "description",
- "enabled")
-DOMAINS_INDEX_URL = 'horizon:admin:domains:index'
-DOMAINS_INDEX_VIEW_TEMPLATE = 'admin/domains/index.html'
-DOMAINS_CREATE_URL = 'horizon:admin:domains:create'
-DOMAINS_UPDATE_URL = 'horizon:admin:domains:update'
diff --git a/openstack_dashboard/dashboards/admin/domains/panel.py b/openstack_dashboard/dashboards/admin/domains/panel.py
deleted file mode 100644
index e6e59166..00000000
--- a/openstack_dashboard/dashboards/admin/domains/panel.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.api.keystone import VERSIONS as IDENTITY_VERSIONS
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Domains(horizon.Panel):
- name = _("Domains")
- slug = 'domains'
-
-
-MULTIDOMAIN_SUPPORT = getattr(settings,
- 'OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT',
- False)
-
-
-if MULTIDOMAIN_SUPPORT and IDENTITY_VERSIONS.active >= 3:
- dashboard.Admin.register(Domains)
diff --git a/openstack_dashboard/dashboards/admin/domains/tables.py b/openstack_dashboard/dashboards/admin/domains/tables.py
deleted file mode 100644
index 702cefe7..00000000
--- a/openstack_dashboard/dashboards/admin/domains/tables.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Hewlett-Packard Development Company, L.P.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from keystoneclient.exceptions import ClientException
-
-from horizon import messages
-from horizon import tables
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.admin.domains.constants \
- import DOMAINS_CREATE_URL
-from openstack_dashboard.dashboards.admin.domains.constants \
- import DOMAINS_INDEX_URL
-from openstack_dashboard.dashboards.admin.domains.constants \
- import DOMAINS_UPDATE_URL
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateDomainLink(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Domain")
- url = DOMAINS_CREATE_URL
- classes = ("ajax-modal", "btn-create")
-
- def allowed(self, request, domain):
- return api.keystone.keystone_can_edit_domain()
-
-
-class EditDomainLink(tables.LinkAction):
- name = "edit"
- verbose_name = _("Edit")
- url = DOMAINS_UPDATE_URL
- classes = ("ajax-modal", "btn-edit")
-
- def allowed(self, request, domain):
- return api.keystone.keystone_can_edit_domain()
-
-
-class DeleteDomainsAction(tables.DeleteAction):
- name = "delete"
- data_type_singular = _("Domain")
- data_type_plural = _("Domains")
-
- def allowed(self, request, datum):
- return api.keystone.keystone_can_edit_domain()
-
- def delete(self, request, obj_id):
- domain = self.table.get_object_by_id(obj_id)
- if domain.enabled:
- msg = _('Domain "%s" must be disabled before it can be deleted.') \
- % domain.name
- messages.error(request, msg)
- raise ClientException(409, msg)
- else:
- LOG.info('Deleting domain "%s".' % obj_id)
- api.keystone.domain_delete(request, obj_id)
-
-
-class DomainFilterAction(tables.FilterAction):
- def filter(self, table, domains, filter_string):
- """ Naive case-insensitive search """
- q = filter_string.lower()
-
- def comp(domain):
- if q in domain.name.lower():
- return True
- return False
-
- return filter(comp, domains)
-
-
-class SetDomainContext(tables.Action):
- name = "set_domain_context"
- verbose_name = _("Set Domain Context")
- url = DOMAINS_INDEX_URL
- preempt = True
-
- def allowed(self, request, datum):
- ctx = request.session.get("domain_context", None)
- if ctx and datum.id == ctx:
- return False
- return True
-
- def single(self, table, request, obj_id):
- if ('domain_context' not in request.session or
- request.session['domain_context'] != obj_id):
- try:
- domain = api.keystone.domain_get(request, obj_id)
- request.session['domain_context'] = obj_id
- request.session['domain_context_name'] = domain.name
- messages.success(request,
- _('Domain Context updated to Domain %s.') %
- domain.name)
- except:
- messages.error(request,
- _('Unable to set Domain Context.'))
-
-
-class UnsetDomainContext(tables.Action):
- name = "clear_domain_context"
- verbose_name = _("Clear Domain Context")
- url = DOMAINS_INDEX_URL
- preempt = True
- requires_input = False
-
- def allowed(self, request, datum):
- ctx = request.session.get("domain_context", None)
- return ctx is not None
-
- def single(self, table, request, obj_id):
- if 'domain_context' in request.session:
- request.session.pop("domain_context")
- request.session.pop("domain_context_name")
- messages.success(request, _('Domain Context cleared.'))
-
-
-class DomainsTable(tables.DataTable):
- name = tables.Column('name', verbose_name=_('Name'))
- description = tables.Column(lambda obj: getattr(obj, 'description', None),
- verbose_name=_('Description'))
- id = tables.Column('id', verbose_name=_('Domain ID'))
- enabled = tables.Column('enabled', verbose_name=_('Enabled'), status=True)
-
- class Meta:
- name = "domains"
- verbose_name = _("Domains")
- row_actions = (SetDomainContext, EditDomainLink, DeleteDomainsAction)
- table_actions = (DomainFilterAction, CreateDomainLink,
- DeleteDomainsAction, UnsetDomainContext)
diff --git a/openstack_dashboard/dashboards/admin/domains/templates/domains/index.html b/openstack_dashboard/dashboards/admin/domains/templates/domains/index.html
deleted file mode 100644
index 78fecfa6..00000000
--- a/openstack_dashboard/dashboards/admin/domains/templates/domains/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Domains" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_domain_page_header.html" with title=_("Domains") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/domains/tests.py b/openstack_dashboard/dashboards/admin/domains/tests.py
deleted file mode 100644
index f3f2e984..00000000
--- a/openstack_dashboard/dashboards/admin/domains/tests.py
+++ /dev/null
@@ -1,228 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IgnoreArg
-from mox import IsA
-
-from horizon.workflows.views import WorkflowView
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-from openstack_dashboard.dashboards.admin.domains.constants \
- import DOMAINS_CREATE_URL as create_url
-from openstack_dashboard.dashboards.admin.domains.constants \
- import DOMAINS_INDEX_URL as index_url
-from openstack_dashboard.dashboards.admin.domains.constants \
- import DOMAINS_INDEX_VIEW_TEMPLATE
-from openstack_dashboard.dashboards.admin.domains.constants \
- import DOMAINS_UPDATE_URL as update_url
-from openstack_dashboard.dashboards.admin.domains.workflows import CreateDomain
-from openstack_dashboard.dashboards.admin.domains.workflows import UpdateDomain
-
-
-DOMAINS_INDEX_URL = reverse(index_url)
-DOMAIN_CREATE_URL = reverse(create_url)
-DOMAIN_UPDATE_URL = reverse(update_url, args=[1])
-
-
-class DomainsViewTests(test.BaseAdminViewTests):
- @test.create_stubs({api.keystone: ('domain_list',)})
- def test_index(self):
- api.keystone.domain_list(IgnoreArg()).AndReturn(self.domains.list())
-
- self.mox.ReplayAll()
-
- res = self.client.get(DOMAINS_INDEX_URL)
-
- self.assertTemplateUsed(res, DOMAINS_INDEX_VIEW_TEMPLATE)
- self.assertItemsEqual(res.context['table'].data, self.domains.list())
- self.assertContains(res, 'Create Domain')
- self.assertContains(res, 'Edit')
- self.assertContains(res, 'Delete Domain')
-
- @test.create_stubs({api.keystone: ('domain_list',
- 'keystone_can_edit_domain')})
- def test_index_with_keystone_can_edit_domain_false(self):
- api.keystone.domain_list(IgnoreArg()).AndReturn(self.domains.list())
- api.keystone.keystone_can_edit_domain() \
- .MultipleTimes().AndReturn(False)
-
- self.mox.ReplayAll()
-
- res = self.client.get(DOMAINS_INDEX_URL)
-
- self.assertTemplateUsed(res, DOMAINS_INDEX_VIEW_TEMPLATE)
- self.assertItemsEqual(res.context['table'].data, self.domains.list())
- self.assertNotContains(res, 'Create Domain')
- self.assertNotContains(res, 'Edit')
- self.assertNotContains(res, 'Delete Domain')
-
- @test.create_stubs({api.keystone: ('domain_list',
- 'domain_delete')})
- def test_delete_domain(self):
- domain = self.domains.get(id="2")
-
- api.keystone.domain_list(IgnoreArg()).AndReturn(self.domains.list())
- api.keystone.domain_delete(IgnoreArg(), domain.id)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'domains__delete__%s' % domain.id}
- res = self.client.post(DOMAINS_INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, DOMAINS_INDEX_URL)
-
- @test.create_stubs({api.keystone: ('domain_list', )})
- def test_delete_with_enabled_domain(self):
- domain = self.domains.get(id="1")
-
- api.keystone.domain_list(IgnoreArg()).AndReturn(self.domains.list())
-
- self.mox.ReplayAll()
-
- formData = {'action': 'domains__delete__%s' % domain.id}
- res = self.client.post(DOMAINS_INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, DOMAINS_INDEX_URL)
- self.assertMessageCount(error=2)
-
- @test.create_stubs({api.keystone: ('domain_get',
- 'domain_list', )})
- def test_set_clear_domain_context(self):
- domain = self.domains.get(id="1")
-
- api.keystone.domain_get(IgnoreArg(), domain.id).AndReturn(domain)
- api.keystone.domain_get(IgnoreArg(), domain.id).AndReturn(domain)
-
- api.keystone.domain_list(IgnoreArg()).AndReturn(self.domains.list())
-
- self.mox.ReplayAll()
-
- formData = {'action': 'domains__set_domain_context__%s' % domain.id}
- res = self.client.post(DOMAINS_INDEX_URL, formData)
-
- self.assertTemplateUsed(res, DOMAINS_INDEX_VIEW_TEMPLATE)
- self.assertItemsEqual(res.context['table'].data, [domain, ])
- self.assertContains(res, "<em>test_domain:</em>")
-
- formData = {'action': 'domains__clear_domain_context__%s' % domain.id}
- res = self.client.post(DOMAINS_INDEX_URL, formData)
-
- self.assertTemplateUsed(res, DOMAINS_INDEX_VIEW_TEMPLATE)
- self.assertItemsEqual(res.context['table'].data, self.domains.list())
- self.assertNotContains(res, "<em>test_domain:</em>")
-
-
-class CreateDomainWorkflowTests(test.BaseAdminViewTests):
- def _get_domain_info(self, domain):
- domain_info = {"name": domain.name,
- "description": domain.description,
- "enabled": domain.enabled}
- return domain_info
-
- def _get_workflow_data(self, domain):
- domain_info = self._get_domain_info(domain)
- return domain_info
-
- def test_add_domain_get(self):
- url = reverse('horizon:admin:domains:create')
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- workflow = res.context['workflow']
- self.assertEqual(res.context['workflow'].name, CreateDomain.name)
-
- self.assertQuerysetEqual(workflow.steps,
- ['<CreateDomainInfo: create_domain>', ])
-
- @test.create_stubs({api.keystone: ('domain_create', )})
- def test_add_domain_post(self):
- domain = self.domains.get(id="1")
-
- api.keystone.domain_create(IsA(http.HttpRequest),
- description=domain.description,
- enabled=domain.enabled,
- name=domain.name).AndReturn(domain)
-
- self.mox.ReplayAll()
-
- workflow_data = self._get_workflow_data(domain)
-
- res = self.client.post(DOMAIN_CREATE_URL, workflow_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, DOMAINS_INDEX_URL)
-
-
-class UpdateDomainWorkflowTests(test.BaseAdminViewTests):
- def _get_domain_info(self, domain):
- domain_info = {"domain_id": domain.id,
- "name": domain.name,
- "description": domain.description,
- "enabled": domain.enabled}
- return domain_info
-
- def _get_workflow_data(self, domain):
- domain_info = self._get_domain_info(domain)
- return domain_info
-
- @test.create_stubs({api.keystone: ('domain_get', )})
- def test_update_domain_get(self):
- domain = self.domains.get(id="1")
-
- api.keystone.domain_get(IsA(http.HttpRequest), '1').AndReturn(domain)
-
- self.mox.ReplayAll()
-
- res = self.client.get(DOMAIN_UPDATE_URL)
-
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- workflow = res.context['workflow']
- self.assertEqual(res.context['workflow'].name, UpdateDomain.name)
-
- self.assertQuerysetEqual(workflow.steps,
- ['<UpdateDomainInfo: update_domain>', ])
-
- @test.create_stubs({api.keystone: ('domain_get',
- 'domain_update')})
- def test_update_domain_post(self):
- domain = self.domains.get(id="1")
- test_description = 'updated description'
-
- api.keystone.domain_get(IsA(http.HttpRequest), '1').AndReturn(domain)
- api.keystone.domain_update(IsA(http.HttpRequest),
- description=test_description,
- domain_id=domain.id,
- enabled=domain.enabled,
- name=domain.name).AndReturn(None)
-
- self.mox.ReplayAll()
-
- workflow_data = self._get_workflow_data(domain)
- workflow_data['description'] = test_description
-
- res = self.client.post(DOMAIN_UPDATE_URL, workflow_data)
-
- self.assertNoFormErrors(res)
- self.assertMessageCount(success=1)
- self.assertRedirectsNoFollow(res, DOMAINS_INDEX_URL)
diff --git a/openstack_dashboard/dashboards/admin/domains/urls.py b/openstack_dashboard/dashboards/admin/domains/urls.py
deleted file mode 100644
index 19448ecf..00000000
--- a/openstack_dashboard/dashboards/admin/domains/urls.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.domains.views import CreateDomainView
-from openstack_dashboard.dashboards.admin.domains.views import IndexView
-from openstack_dashboard.dashboards.admin.domains.views import UpdateDomainView
-
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^create$', CreateDomainView.as_view(), name='create'),
- url(r'^(?P<domain_id>[^/]+)/update/$',
- UpdateDomainView.as_view(), name='update')
-)
diff --git a/openstack_dashboard/dashboards/admin/domains/views.py b/openstack_dashboard/dashboards/admin/domains/views.py
deleted file mode 100644
index dedec4e8..00000000
--- a/openstack_dashboard/dashboards/admin/domains/views.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-from horizon import workflows
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.admin.domains.constants \
- import DOMAIN_INFO_FIELDS
-from openstack_dashboard.dashboards.admin.domains.constants \
- import DOMAINS_INDEX_URL
-from openstack_dashboard.dashboards.admin.domains.constants \
- import DOMAINS_INDEX_VIEW_TEMPLATE
-from openstack_dashboard.dashboards.admin.domains.tables import DomainsTable
-from openstack_dashboard.dashboards.admin.domains.workflows \
- import CreateDomain
-from openstack_dashboard.dashboards.admin.domains.workflows \
- import UpdateDomain
-
-
-class IndexView(tables.DataTableView):
- table_class = DomainsTable
- template_name = DOMAINS_INDEX_VIEW_TEMPLATE
-
- def get_data(self):
- domains = []
- domain_context = self.request.session.get('domain_context', None)
- try:
- if domain_context:
- domain = api.keystone.domain_get(self.request,
- domain_context)
- domains.append(domain)
- else:
- domains = api.keystone.domain_list(self.request)
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve domain list.'))
- return domains
-
-
-class CreateDomainView(workflows.WorkflowView):
- workflow_class = CreateDomain
-
-
-class UpdateDomainView(workflows.WorkflowView):
- workflow_class = UpdateDomain
-
- def get_initial(self):
- initial = super(UpdateDomainView, self).get_initial()
-
- domain_id = self.kwargs['domain_id']
- initial['domain_id'] = domain_id
-
- try:
- # get initial domain info
- domain_info = api.keystone.domain_get(self.request,
- domain_id)
- for field in DOMAIN_INFO_FIELDS:
- initial[field] = getattr(domain_info, field, None)
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve domain details.'),
- redirect=reverse(DOMAINS_INDEX_URL))
- return initial
diff --git a/openstack_dashboard/dashboards/admin/domains/workflows.py b/openstack_dashboard/dashboards/admin/domains/workflows.py
deleted file mode 100644
index d810553e..00000000
--- a/openstack_dashboard/dashboards/admin/domains/workflows.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Hewlett-Packard Development Company, L.P.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import workflows
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.admin.domains.constants \
- import DOMAINS_INDEX_URL
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateDomainInfoAction(workflows.Action):
- name = forms.CharField(label=_("Name"),
- required=True)
- description = forms.CharField(widget=forms.widgets.Textarea(),
- label=_("Description"),
- required=False)
- enabled = forms.BooleanField(label=_("Enabled"),
- required=False,
- initial=True)
-
- class Meta:
- name = _("Domain Info")
- slug = "create_domain"
- help_text = _("From here you can create a new domain to organize "
- "projects, groups and users.")
-
-
-class CreateDomainInfo(workflows.Step):
- action_class = CreateDomainInfoAction
- contributes = ("domain_id",
- "name",
- "description",
- "enabled")
-
-
-class CreateDomain(workflows.Workflow):
- slug = "create_domain"
- name = _("Create Domain")
- finalize_button_name = _("Create Domain")
- success_message = _('Created new domain "%s".')
- failure_message = _('Unable to create domain "%s".')
- success_url = DOMAINS_INDEX_URL
- default_steps = (CreateDomainInfo, )
-
- def format_status_message(self, message):
- return message % self.context.get('name', 'unknown domain')
-
- def handle(self, request, data):
- # create the domain
- try:
- LOG.info('Creating domain with name "%s"' % data['name'])
- desc = data['description']
- api.keystone.domain_create(request,
- name=data['name'],
- description=desc,
- enabled=data['enabled'])
- except:
- exceptions.handle(request, ignore=True)
- return False
-
- return True
-
-
-class UpdateDomainInfoAction(CreateDomainInfoAction):
-
- class Meta:
- name = _("Domain Info")
- slug = 'update_domain'
- help_text = _("From here you can edit the domain details.")
-
-
-class UpdateDomainInfo(workflows.Step):
- action_class = UpdateDomainInfoAction
- depends_on = ("domain_id",)
- contributes = ("name",
- "description",
- "enabled")
-
-
-class UpdateDomain(workflows.Workflow):
- slug = "update_domain"
- name = _("Edit Domain")
- finalize_button_name = _("Save")
- success_message = _('Modified domain "%s".')
- failure_message = _('Unable to modify domain "%s".')
- success_url = DOMAINS_INDEX_URL
- default_steps = (UpdateDomainInfo, )
-
- def format_status_message(self, message):
- return message % self.context.get('name', 'unknown domain')
-
- def handle(self, request, data):
- domain_id = data.pop('domain_id')
-
- try:
- LOG.info('Updating domain with name "%s"' % data['name'])
- api.keystone.domain_update(request,
- domain_id=domain_id,
- name=data['name'],
- description=data['description'],
- enabled=data['enabled'])
- except:
- exceptions.handle(request, ignore=True)
- return False
- return True
diff --git a/openstack_dashboard/dashboards/admin/flavors/__init__.py b/openstack_dashboard/dashboards/admin/flavors/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/flavors/extras/__init__.py b/openstack_dashboard/dashboards/admin/flavors/extras/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/extras/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/flavors/extras/forms.py b/openstack_dashboard/dashboards/admin/flavors/extras/forms.py
deleted file mode 100644
index 3cdbf229..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/extras/forms.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright (c) 2012 Intel, 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 logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from openstack_dashboard import api
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateExtraSpec(forms.SelfHandlingForm):
- key = forms.CharField(max_length="25", label=_("Key"))
- value = forms.CharField(max_length="25", label=_("Value"))
- flavor_id = forms.CharField(widget=forms.widgets.HiddenInput)
-
- def handle(self, request, data):
- try:
- api.nova.flavor_extra_set(request,
- data['flavor_id'],
- {data['key']: data['value']})
- msg = _('Created extra spec "%s".') % data['key']
- messages.success(request, msg)
- return True
- except:
- exceptions.handle(request,
- _("Unable to create flavor extra spec."))
-
-
-class EditExtraSpec(forms.SelfHandlingForm):
- key = forms.CharField(max_length="25", label=_("Key"))
- value = forms.CharField(max_length="25", label=_("Value"))
- flavor_id = forms.CharField(widget=forms.widgets.HiddenInput)
-
- def handle(self, request, data):
- flavor_id = data['flavor_id']
- try:
- api.nova.flavor_extra_set(request,
- flavor_id,
- {data['key']: data['value']})
- msg = _('Saved extra spec "%s".') % data['key']
- messages.success(request, msg)
- return True
- except:
- exceptions.handle(request, _("Unable to edit extra spec."))
diff --git a/openstack_dashboard/dashboards/admin/flavors/extras/tables.py b/openstack_dashboard/dashboards/admin/flavors/extras/tables.py
deleted file mode 100644
index f8f8e07a..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/extras/tables.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 Intel, 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 logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class ExtraSpecDelete(tables.DeleteAction):
- data_type_singular = _("ExtraSpec")
- data_type_plural = _("ExtraSpecs")
-
- def delete(self, request, obj_ids):
- flavor = api.nova.flavor_get(request, self.table.kwargs['id'])
- flavor.unset_keys([obj_ids])
-
-
-class ExtraSpecCreate(tables.LinkAction):
- name = "create"
- verbose_name = _("Create")
- url = "horizon:admin:flavors:extras:create"
- classes = ("btn-create", "ajax-modal")
-
- def get_link_url(self, extra_spec=None):
- return reverse(self.url, args=[self.table.kwargs['id']])
-
-
-class ExtraSpecEdit(tables.LinkAction):
- name = "edit"
- verbose_name = _("Edit")
- url = "horizon:admin:flavors:extras:edit"
- classes = ("btn-edit", "ajax-modal")
-
- def get_link_url(self, extra_spec):
- return reverse(self.url, args=[self.table.kwargs['id'],
- extra_spec.key])
-
-
-class ExtraSpecsTable(tables.DataTable):
- key = tables.Column('key', verbose_name=_('Key'))
- value = tables.Column('value', verbose_name=_('Value'))
-
- class Meta:
- name = "extras"
- verbose_name = _("Extra Specs")
- table_actions = (ExtraSpecCreate, ExtraSpecDelete)
- row_actions = (ExtraSpecEdit, ExtraSpecDelete)
-
- def get_object_id(self, datum):
- return datum.key
-
- def get_object_display(self, datum):
- return datum.key
diff --git a/openstack_dashboard/dashboards/admin/flavors/extras/tests.py b/openstack_dashboard/dashboards/admin/flavors/extras/tests.py
deleted file mode 100644
index 946645a0..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/extras/tests.py
+++ /dev/null
@@ -1,62 +0,0 @@
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class FlavorExtrasTests(test.BaseAdminViewTests):
-
- @test.create_stubs({api.nova: ('flavor_get_extras',
- 'flavor_get'), })
- def test_list_extras_when_none_exists(self):
- flavor = self.flavors.first()
- extras = [api.nova.FlavorExtraSpec(flavor.id, 'k1', 'v1')]
-
- # GET -- to determine correctness of output
- api.nova.flavor_get(IsA(http.HttpRequest), flavor.id).AndReturn(flavor)
- api.nova.flavor_get_extras(IsA(http.HttpRequest),
- flavor.id).AndReturn(extras)
- self.mox.ReplayAll()
- url = reverse('horizon:admin:flavors:extras:index', args=[flavor.id])
- resp = self.client.get(url)
- self.assertEqual(resp.status_code, 200)
- self.assertTemplateUsed(resp, "admin/flavors/extras/index.html")
-
- @test.create_stubs({api.nova: ('flavor_extra_set', ), })
- def test_extra_create_post(self):
- flavor = self.flavors.first()
- create_url = reverse('horizon:admin:flavors:extras:create',
- args=[flavor.id])
- index_url = reverse('horizon:admin:flavors:extras:index',
- args=[flavor.id])
-
- # GET to display the flavor_name
- api.nova.flavor_extra_set(IsA(http.HttpRequest),
- flavor.id,
- {'k1': 'v1'})
- self.mox.ReplayAll()
-
- data = {'flavor_id': flavor.id,
- 'key': 'k1',
- 'value': 'v1'}
- resp = self.client.post(create_url, data)
- self.assertNoFormErrors(resp)
- self.assertMessageCount(success=1)
- self.assertRedirectsNoFollow(resp, index_url)
-
- @test.create_stubs({api.nova: ('flavor_get', ), })
- def test_extra_create_get(self):
- flavor = self.flavors.first()
- create_url = reverse('horizon:admin:flavors:extras:create',
- args=[flavor.id])
-
- api.nova.flavor_get(IsA(http.HttpRequest), flavor.id).AndReturn(flavor)
- self.mox.ReplayAll()
-
- resp = self.client.get(create_url)
- self.assertEqual(resp.status_code, 200)
- self.assertTemplateUsed(resp,
- 'admin/flavors/extras/create.html')
diff --git a/openstack_dashboard/dashboards/admin/flavors/extras/urls.py b/openstack_dashboard/dashboards/admin/flavors/extras/urls.py
deleted file mode 100644
index 17812a8b..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/extras/urls.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.flavors.extras.views \
- import CreateView
-from openstack_dashboard.dashboards.admin.flavors.extras.views import EditView
-from openstack_dashboard.dashboards.admin.flavors.extras.views import IndexView
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^create/$', CreateView.as_view(), name='create'),
- url(r'^(?P<key>[^/]+)/edit/$', EditView.as_view(), name='edit')
-)
diff --git a/openstack_dashboard/dashboards/admin/flavors/extras/views.py b/openstack_dashboard/dashboards/admin/flavors/extras/views.py
deleted file mode 100644
index ffb074c6..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/extras/views.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright (c) 2012 Intel, 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 logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.admin.flavors.extras.forms \
- import CreateExtraSpec
-from openstack_dashboard.dashboards.admin.flavors.extras.forms \
- import EditExtraSpec
-from openstack_dashboard.dashboards.admin.flavors.extras.tables \
- import ExtraSpecsTable
-
-
-LOG = logging.getLogger(__name__)
-
-
-class ExtraSpecMixin(object):
- def get_context_data(self, **kwargs):
- context = super(ExtraSpecMixin, self).get_context_data(**kwargs)
- try:
- context['flavor'] = api.nova.flavor_get(self.request,
- self.kwargs['id'])
- except:
- exceptions.handle(self.request,
- _("Unable to retrieve flavor data."))
- return context
-
-
-class IndexView(ExtraSpecMixin, forms.ModalFormMixin, tables.DataTableView):
- table_class = ExtraSpecsTable
- template_name = 'admin/flavors/extras/index.html'
-
- def get_data(self):
- try:
- flavor_id = self.kwargs['id']
- extras_list = api.nova.flavor_get_extras(self.request, flavor_id)
- extras_list.sort(key=lambda es: (es.key,))
- except:
- extras_list = []
- exceptions.handle(self.request,
- _('Unable to retrieve extra spec list.'))
- return extras_list
-
-
-class CreateView(ExtraSpecMixin, forms.ModalFormView):
- form_class = CreateExtraSpec
- template_name = 'admin/flavors/extras/create.html'
-
- def get_initial(self):
- return {'flavor_id': self.kwargs['id']}
-
- def get_success_url(self):
- return "/admin/flavors/%s/extras/" % (self.kwargs['id'])
-
-
-class EditView(ExtraSpecMixin, forms.ModalFormView):
- form_class = EditExtraSpec
- template_name = 'admin/flavors/extras/edit.html'
-
- def get_initial(self):
- flavor_id = self.kwargs['id']
- key = self.kwargs['key']
- try:
- extra_specs = api.nova.flavor_get_extras(self.request,
- flavor_id,
- raw=True)
- except:
- extra_specs = {}
- exceptions.handle(self.request,
- _("Unable to retrieve flavor extra spec data."))
- return {'flavor_id': flavor_id,
- 'key': key,
- 'value': extra_specs.get(key, '')}
diff --git a/openstack_dashboard/dashboards/admin/flavors/forms.py b/openstack_dashboard/dashboards/admin/flavors/forms.py
deleted file mode 100644
index 4f17e8a6..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/forms.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateFlavor(forms.SelfHandlingForm):
- _flavor_id_regex = (r'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-'
- r'[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|[0-9]+|auto$')
- _flavor_id_help_text = _("Flavor ID should be UUID4 or integer. "
- "Leave this field blank or use 'auto' to set "
- "a random UUID4.")
- name = forms.RegexField(label=_("Name"),
- max_length=25,
- regex=r'^[\w\.\- ]+$',
- error_messages={'invalid': _('Name may only '
- 'contain letters, numbers, underscores, '
- 'periods and hyphens.')})
- flavor_id = forms.RegexField(label=_("ID"),
- regex=_flavor_id_regex,
- required=False,
- initial='auto',
- help_text=_flavor_id_help_text)
- vcpus = forms.IntegerField(label=_("VCPUs"))
- memory_mb = forms.IntegerField(label=_("RAM MB"))
- disk_gb = forms.IntegerField(label=_("Root Disk GB"))
- eph_gb = forms.IntegerField(label=_("Ephemeral Disk GB"))
- swap_mb = forms.IntegerField(label=_("Swap Disk MB"))
-
- def clean_name(self):
- name = self.cleaned_data.get('name')
- try:
- flavors = api.nova.flavor_list(self.request)
- except:
- flavors = []
- msg = _('Unable to get flavor list')
- exceptions.check_message(["Connection", "refused"], msg)
- raise
- if flavors is not None:
- for flavor in flavors:
- if flavor.name == name:
- raise forms.ValidationError(
- _('The name "%s" is already used by another flavor.')
- % name
- )
- return name
-
- def clean_flavor_id(self):
- flavor_id = self.data.get('flavor_id')
- try:
- flavors = api.nova.flavor_list(self.request)
- except:
- flavors = []
- msg = _('Unable to get flavor list')
- exceptions.check_message(["Connection", "refused"], msg)
- raise
- if flavors is not None:
- for flavor in flavors:
- if flavor.id == flavor_id:
- raise forms.ValidationError(
- _('The ID "%s" is already used by another flavor.')
- % flavor_id
- )
- return flavor_id
-
- def handle(self, request, data):
- try:
- flavor = api.nova.flavor_create(request,
- data['name'],
- data['memory_mb'],
- data['vcpus'],
- data['disk_gb'],
- flavorid=data["flavor_id"],
- ephemeral=data['eph_gb'],
- swap=data['swap_mb'])
- msg = _('Created flavor "%s".') % data['name']
- messages.success(request, msg)
- return flavor
- except:
- exceptions.handle(request, _("Unable to create flavor."))
-
-
-class EditFlavor(CreateFlavor):
- flavor_id = forms.CharField(widget=forms.widgets.HiddenInput)
-
- def clean_flavor_id(self):
- return self.data.get('flavor_id')
-
- def handle(self, request, data):
- try:
- flavor_id = data['flavor_id']
- # grab any existing extra specs, because flavor edit currently
- # implemented as a delete followed by a create
- extras_dict = api.nova.flavor_get_extras(self.request,
- flavor_id,
- raw=True)
- # First mark the existing flavor as deleted.
- api.nova.flavor_delete(request, data['flavor_id'])
- # Then create a new flavor with the same name but a new ID.
- # This is in the same try/except block as the delete call
- # because if the delete fails the API will error out because
- # active flavors can't have the same name.
- flavor = api.nova.flavor_create(request,
- data['name'],
- data['memory_mb'],
- data['vcpus'],
- data['disk_gb'],
- ephemeral=data['eph_gb'],
- swap=data['swap_mb'])
- if (extras_dict):
- api.nova.flavor_extra_set(request, flavor.id, extras_dict)
- msg = _('Updated flavor "%s".') % data['name']
- messages.success(request, msg)
- return flavor
- except:
- exceptions.handle(request, _("Unable to update flavor."))
diff --git a/openstack_dashboard/dashboards/admin/flavors/panel.py b/openstack_dashboard/dashboards/admin/flavors/panel.py
deleted file mode 100644
index 2f769b02..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/panel.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Flavors(horizon.Panel):
- name = _("Flavors")
- slug = 'flavors'
-
-
-dashboard.Admin.register(Flavors)
diff --git a/openstack_dashboard/dashboards/admin/flavors/tables.py b/openstack_dashboard/dashboards/admin/flavors/tables.py
deleted file mode 100644
index d5428c73..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/tables.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DeleteFlavor(tables.DeleteAction):
- data_type_singular = _("Flavor")
- data_type_plural = _("Flavors")
-
- def delete(self, request, obj_id):
- api.nova.flavor_delete(request, obj_id)
-
-
-class CreateFlavor(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Flavor")
- url = "horizon:admin:flavors:create"
- classes = ("ajax-modal", "btn-create")
-
-
-class EditFlavor(tables.LinkAction):
- name = "edit"
- verbose_name = _("Edit Flavor")
- url = "horizon:admin:flavors:edit"
- classes = ("ajax-modal", "btn-edit")
-
-
-class ViewFlavorExtras(tables.LinkAction):
- name = "extras"
- verbose_name = _("View Extra Specs")
- url = "horizon:admin:flavors:extras:index"
- classes = ("btn-edit",)
-
-
-def get_size(flavor):
- return _("%sMB") % flavor.ram
-
-
-def get_swap_size(flavor):
- return _("%sMB") % (flavor.swap or 0)
-
-
-class FlavorsTable(tables.DataTable):
- name = tables.Column('name', verbose_name=_('Flavor Name'))
- vcpus = tables.Column('vcpus', verbose_name=_('VCPUs'))
- ram = tables.Column(get_size,
- verbose_name=_('RAM'),
- attrs={'data-type': 'size'})
- disk = tables.Column('disk', verbose_name=_('Root Disk'))
- ephemeral = tables.Column('OS-FLV-EXT-DATA:ephemeral',
- verbose_name=_('Ephemeral Disk'))
- swap = tables.Column(get_swap_size,
- verbose_name=_('Swap Disk'),
- attrs={'data-type': 'size'})
- flavor_id = tables.Column('id', verbose_name=('ID'))
-
- class Meta:
- name = "flavors"
- verbose_name = _("Flavors")
- table_actions = (CreateFlavor, DeleteFlavor)
- row_actions = (EditFlavor, ViewFlavorExtras, DeleteFlavor)
diff --git a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/_create.html b/openstack_dashboard/dashboards/admin/flavors/templates/flavors/_create.html
deleted file mode 100644
index d50aa7ea..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/_create.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_flavor_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:flavors:create' %}{% endblock %}
-
-{% block modal_id %}create_flavor_modal{% endblock %}
-{% block modal-header %}{% trans "Create Flavor" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can define the sizing of a new flavor." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Flavor" %}" />
- <a href="{% url 'horizon:admin:flavors:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/_edit.html b/openstack_dashboard/dashboards/admin/flavors/templates/flavors/_edit.html
deleted file mode 100644
index d5c5efe8..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/_edit.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}edit_flavor_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:flavors:edit' flavor_id %}{% endblock %}
-
-{% block modal_id %}edit_flavor_modal{% endblock %}
-{% block modal-header %}{% trans "Edit Flavor" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can alter the sizing of the current flavor." %}</p>
- <p>{% trans "Note: this will not affect the resources allocated to any existing instances using this flavor." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save" %}" />
- <a href="{% url 'horizon:admin:flavors:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/create.html b/openstack_dashboard/dashboards/admin/flavors/templates/flavors/create.html
deleted file mode 100644
index 377ed0e6..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Flavor" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create Flavor") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "admin/flavors/_create.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/edit.html b/openstack_dashboard/dashboards/admin/flavors/templates/flavors/edit.html
deleted file mode 100644
index 8a634b44..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/edit.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Edit Flavor" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Edit Flavor") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "admin/flavors/_edit.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_create.html b/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_create.html
deleted file mode 100644
index 2192658f..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_create.html
+++ /dev/null
@@ -1,28 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}extra_spec_create_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:flavors:extras:create' flavor.id %}{% endblock %}
-
-
-{% block modal_id %}extra_spec_create_modal{% endblock %}
-{% block modal-header %}{% trans "Create Flavor Extra Spec" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans 'Create a new "extra spec" key-value pair for a flavor.' %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create" %}" />
- <a href="{% url 'horizon:admin:flavors:extras:index' flavor.id %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
-
diff --git a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_edit.html b/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_edit.html
deleted file mode 100644
index 74800829..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_edit.html
+++ /dev/null
@@ -1,28 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}extra_spec_edit_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:flavors:extras:create' flavor.id %}{% endblock %}
-
-
-{% block modal_id %}extra_spec_edit_modal{% endblock %}
-{% block modal-header %}{% trans "Edit Flavor Extra Spec" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans 'Update an "extra spec" key-value pair for a flavor.' %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save" %}" />
- <a href="{% url 'horizon:admin:flavors:extras:index' flavor.id %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
-
diff --git a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_index.html b/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_index.html
deleted file mode 100644
index da96be95..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/_index.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends "horizon/common/_modal.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block modal_id %}extra_specs_modal{% endblock %}
-{% block modal-header %}{% trans "Flavor Extra Specs" %}{% endblock %}
-
-{% block modal-body %}
- {{ table.render }}
-{% endblock %}
-
-{% block modal-footer %}
- <a href="{% url 'horizon:admin:flavors:index' %}" class="btn secondary cancel close">{% trans "Close" %}</a>
-{% endblock %}
-
diff --git a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/create.html b/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/create.html
deleted file mode 100644
index 20461837..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/create.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-
-{% block title %}{% trans "Create Flavor Extra Spec" %}{% endblock %}
-
-{% block page_header %}
- <h2>{% trans "Flavor" %}: {{flavor.name}} </h2>
-{% endblock page_header %}
-
-{% block main %}
- {% include "admin/flavors/extras/_create.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/edit.html b/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/edit.html
deleted file mode 100644
index c471844e..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/edit.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-
-{% block title %}{% trans "Edit Flavor Extra Spec" %}{% endblock %}
-
-{% block page_header %}
- <h2>{% trans "Flavor" %}: {{flavor.name}} </h2>
-{% endblock page_header %}
-
-{% block main %}
- {% include "admin/flavors/extras/_edit.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/index.html b/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/index.html
deleted file mode 100644
index fbe91eff..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/extras/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-
-{% block title %}{% trans "Flavor Extra Specs" %}{% endblock %}
-
-{% block page_header %}
- <h2>{% trans "Flavor" %}: {{flavor.name}} </h2>
-{% endblock page_header %}
-
-{% block main %}
- {% include "admin/flavors/extras/_index.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/index.html b/openstack_dashboard/dashboards/admin/flavors/templates/flavors/index.html
deleted file mode 100644
index 3a306e57..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/templates/flavors/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Flavors" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Flavors") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/flavors/tests.py b/openstack_dashboard/dashboards/admin/flavors/tests.py
deleted file mode 100644
index 82c33e3d..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/tests.py
+++ /dev/null
@@ -1,234 +0,0 @@
-from django.core.urlresolvers import reverse
-from django import http
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-from novaclient.v1_1 import flavors
-
-
-class FlavorsTests(test.BaseAdminViewTests):
- @test.create_stubs({api.nova: ('flavor_list', 'flavor_create'), })
- def test_create_new_flavor_when_none_exist(self):
- flavor = self.flavors.first()
- eph = getattr(flavor, 'OS-FLV-EXT-DATA:ephemeral')
-
- # no pre-existing flavors
- api.nova.flavor_create(IsA(http.HttpRequest),
- flavor.name,
- flavor.ram,
- flavor.vcpus,
- flavor.disk,
- flavorid=flavor.id,
- swap=flavor.swap,
- ephemeral=eph).AndReturn(flavor)
- api.nova.flavor_list(IsA(http.HttpRequest))
- api.nova.flavor_list(IsA(http.HttpRequest))
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:flavors:create')
- resp = self.client.get(url)
- self.assertEqual(resp.status_code, 200)
- self.assertTemplateUsed(resp, "admin/flavors/create.html")
-
- data = {'name': flavor.name,
- 'flavor_id': flavor.id,
- 'vcpus': flavor.vcpus,
- 'memory_mb': flavor.ram,
- 'disk_gb': flavor.disk,
- 'swap_mb': flavor.swap,
- 'eph_gb': eph}
- resp = self.client.post(url, data)
- self.assertRedirectsNoFollow(resp,
- reverse("horizon:admin:flavors:index"))
-
- # keeping the 2 edit tests separate to aid debug breaks
- @test.create_stubs({api.nova: ('flavor_list',
- 'flavor_create',
- 'flavor_delete',
- 'flavor_get_extras',
- 'flavor_get'), })
- def test_edit_flavor(self):
- flavor = self.flavors.first() # has no extra specs
- eph = getattr(flavor, 'OS-FLV-EXT-DATA:ephemeral')
- extra_specs = getattr(flavor, 'extra_specs')
- new_flavor = flavors.Flavor(flavors.FlavorManager(None),
- {'id':
- "cccccccc-cccc-cccc-cccc-cccccccccccc",
- 'name': flavor.name,
- 'vcpus': flavor.vcpus + 1,
- 'disk': flavor.disk,
- 'ram': flavor.ram,
- 'swap': 0,
- 'OS-FLV-EXT-DATA:ephemeral': eph,
- 'extra_specs': extra_specs})
- # GET
- api.nova.flavor_get(IsA(http.HttpRequest), flavor.id).AndReturn(flavor)
-
- # POST
- api.nova.flavor_list(IsA(http.HttpRequest))
- api.nova.flavor_get(IsA(http.HttpRequest), flavor.id).AndReturn(flavor)
- api.nova.flavor_get_extras(IsA(http.HttpRequest), flavor.id, raw=True)\
- .AndReturn(extra_specs)
- api.nova.flavor_delete(IsA(http.HttpRequest), flavor.id)
- api.nova.flavor_create(IsA(http.HttpRequest),
- new_flavor.name,
- new_flavor.ram,
- new_flavor.vcpus,
- new_flavor.disk,
- swap=flavor.swap,
- ephemeral=eph).AndReturn(new_flavor)
- self.mox.ReplayAll()
-
- # get_test
- url = reverse('horizon:admin:flavors:edit', args=[flavor.id])
- resp = self.client.get(url)
- self.assertEqual(resp.status_code, 200)
- self.assertTemplateUsed(resp, "admin/flavors/edit.html")
-
- # post test
- data = {'flavor_id': flavor.id,
- 'name': flavor.name,
- 'vcpus': flavor.vcpus + 1,
- 'memory_mb': flavor.ram,
- 'disk_gb': flavor.disk,
- 'swap_mb': flavor.swap,
- 'eph_gb': eph}
- resp = self.client.post(url, data)
- self.assertNoFormErrors(resp)
- self.assertMessageCount(success=1)
- self.assertRedirectsNoFollow(resp,
- reverse("horizon:admin:flavors:index"))
-
- @test.create_stubs({api.nova: ('flavor_list',
- 'flavor_create',
- 'flavor_delete',
- 'flavor_get_extras',
- 'flavor_extra_set',
- 'flavor_get'), })
- def test_edit_flavor_with_extra_specs(self):
- flavor = self.flavors.list()[1] # the second element has extra specs
- eph = getattr(flavor, 'OS-FLV-EXT-DATA:ephemeral')
- extra_specs = getattr(flavor, 'extra_specs')
- new_vcpus = flavor.vcpus + 1
- new_flavor = flavors.Flavor(flavors.FlavorManager(None),
- {'id':
- "cccccccc-cccc-cccc-cccc-cccccccccccc",
- 'name': flavor.name,
- 'vcpus': new_vcpus,
- 'disk': flavor.disk,
- 'ram': flavor.ram,
- 'swap': flavor.swap,
- 'OS-FLV-EXT-DATA:ephemeral': eph,
- 'extra_specs': extra_specs})
- # GET
- api.nova.flavor_get(IsA(http.HttpRequest), flavor.id).AndReturn(flavor)
-
- # POST
- api.nova.flavor_list(IsA(http.HttpRequest))
- api.nova.flavor_get(IsA(http.HttpRequest), flavor.id).AndReturn(flavor)
- api.nova.flavor_get_extras(IsA(http.HttpRequest), flavor.id, raw=True)\
- .AndReturn(extra_specs)
- api.nova.flavor_delete(IsA(http.HttpRequest), flavor.id)
- api.nova.flavor_create(IsA(http.HttpRequest),
- flavor.name,
- flavor.ram,
- new_vcpus,
- flavor.disk,
- swap=flavor.swap,
- ephemeral=eph).AndReturn(new_flavor)
- api.nova.flavor_extra_set(IsA(http.HttpRequest),
- new_flavor.id,
- extra_specs)
- self.mox.ReplayAll()
-
- #get_test
- url = reverse('horizon:admin:flavors:edit', args=[flavor.id])
- resp = self.client.get(url)
- self.assertEqual(resp.status_code, 200)
- self.assertTemplateUsed(resp, "admin/flavors/edit.html")
-
- #post test
- data = {'flavor_id': flavor.id,
- 'name': flavor.name,
- 'vcpus': new_vcpus,
- 'memory_mb': flavor.ram,
- 'disk_gb': flavor.disk,
- 'swap_mb': flavor.swap,
- 'eph_gb': eph}
- resp = self.client.post(url, data)
- self.assertNoFormErrors(resp)
- self.assertMessageCount(success=1)
- self.assertRedirectsNoFollow(resp,
- reverse("horizon:admin:flavors:index"))
-
- @test.create_stubs({api.nova: ('flavor_list',
- 'flavor_get'), })
- def test_edit_flavor_set_invalid_name(self):
- flavor_a = self.flavors.list()[0]
- eph = getattr(flavor_a, 'OS-FLV-EXT-DATA:ephemeral')
- invalid_flavor_name = "m1.tiny()"
-
- # GET
- api.nova.flavor_get(IsA(http.HttpRequest),
- flavor_a.id).AndReturn(flavor_a)
-
- # POST
- api.nova.flavor_get(IsA(http.HttpRequest),
- flavor_a.id).AndReturn(flavor_a)
- self.mox.ReplayAll()
-
- # get_test
- url = reverse('horizon:admin:flavors:edit', args=[flavor_a.id])
- resp = self.client.get(url)
- self.assertEqual(resp.status_code, 200)
- self.assertTemplateUsed(resp, "admin/flavors/edit.html")
-
- # post test
- data = {'flavor_id': flavor_a.id,
- 'name': invalid_flavor_name,
- 'vcpus': flavor_a.vcpus + 1,
- 'memory_mb': flavor_a.ram,
- 'disk_gb': flavor_a.disk,
- 'swap_mb': flavor_a.swap,
- 'eph_gb': eph}
- resp = self.client.post(url, data)
- self.assertFormErrors(resp, 1, 'Name may only contain letters, '
- 'numbers, underscores, periods and hyphens.')
-
- @test.create_stubs({api.nova: ('flavor_list',
- 'flavor_get'), })
- def test_edit_flavor_set_existing_name(self):
- flavor_a = self.flavors.list()[0]
- flavor_b = self.flavors.list()[1]
- eph = getattr(flavor_a, 'OS-FLV-EXT-DATA:ephemeral')
-
- # GET
- api.nova.flavor_get(IsA(http.HttpRequest),
- flavor_a.id).AndReturn(flavor_a)
-
- # POST
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.flavor_get(IsA(http.HttpRequest),
- flavor_a.id).AndReturn(flavor_a)
- self.mox.ReplayAll()
-
- # get_test
- url = reverse('horizon:admin:flavors:edit', args=[flavor_a.id])
- resp = self.client.get(url)
- self.assertEqual(resp.status_code, 200)
- self.assertTemplateUsed(resp, "admin/flavors/edit.html")
-
- # post test
- data = {'flavor_id': flavor_a.id,
- 'name': flavor_b.name,
- 'vcpus': flavor_a.vcpus + 1,
- 'memory_mb': flavor_a.ram,
- 'disk_gb': flavor_a.disk,
- 'swap_mb': flavor_a.swap,
- 'eph_gb': eph}
- resp = self.client.post(url, data)
- self.assertFormErrors(resp, 1, 'The name &quot;m1.massive&quot; '
- 'is already used by another flavor.')
diff --git a/openstack_dashboard/dashboards/admin/flavors/urls.py b/openstack_dashboard/dashboards/admin/flavors/urls.py
deleted file mode 100644
index 7ef8c91f..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/urls.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import include
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.flavors.extras \
- import urls as extras_urls
-from openstack_dashboard.dashboards.admin.flavors.views import CreateView
-from openstack_dashboard.dashboards.admin.flavors.views import EditView
-from openstack_dashboard.dashboards.admin.flavors.views import IndexView
-
-urlpatterns = patterns('openstack_dashboard.dashboards.admin.flavors.views',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^create/$', CreateView.as_view(), name='create'),
- url(r'^(?P<id>[^/]+)/edit/$', EditView.as_view(), name='edit'),
- url(r'^(?P<id>[^/]+)/extras/', include(extras_urls, namespace='extras')),
-)
diff --git a/openstack_dashboard/dashboards/admin/flavors/views.py b/openstack_dashboard/dashboards/admin/flavors/views.py
deleted file mode 100644
index 91fbe5b0..00000000
--- a/openstack_dashboard/dashboards/admin/flavors/views.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.admin.flavors.forms import CreateFlavor
-from openstack_dashboard.dashboards.admin.flavors.forms import EditFlavor
-from openstack_dashboard.dashboards.admin.flavors.tables import FlavorsTable
-
-
-LOG = logging.getLogger(__name__)
-
-
-class IndexView(tables.DataTableView):
- table_class = FlavorsTable
- template_name = 'admin/flavors/index.html'
-
- def get_data(self):
- request = self.request
- flavors = []
- try:
- flavors = api.nova.flavor_list(request)
- except:
- exceptions.handle(request,
- _('Unable to retrieve flavor list.'))
- # Sort flavors by size
- flavors.sort(key=lambda f: (f.vcpus, f.ram, f.disk))
- return flavors
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateFlavor
- template_name = 'admin/flavors/create.html'
- success_url = reverse_lazy('horizon:admin:flavors:index')
-
-
-class EditView(forms.ModalFormView):
- form_class = EditFlavor
- template_name = 'admin/flavors/edit.html'
- success_url = reverse_lazy('horizon:admin:flavors:index')
-
- def get_context_data(self, **kwargs):
- context = super(EditView, self).get_context_data(**kwargs)
- context['flavor_id'] = self.kwargs['id']
- return context
-
- def get_initial(self):
- try:
- flavor = api.nova.flavor_get(self.request, self.kwargs['id'])
- except:
- exceptions.handle(self.request,
- _("Unable to retrieve flavor data."))
- return {'flavor_id': flavor.id,
- 'name': flavor.name,
- 'vcpus': flavor.vcpus,
- 'memory_mb': flavor.ram,
- 'disk_gb': flavor.disk,
- 'swap_mb': flavor.swap or 0,
- 'eph_gb': getattr(flavor, 'OS-FLV-EXT-DATA:ephemeral', None)}
diff --git a/openstack_dashboard/dashboards/admin/groups/__init__.py b/openstack_dashboard/dashboards/admin/groups/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/groups/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/groups/constants.py b/openstack_dashboard/dashboards/admin/groups/constants.py
deleted file mode 100644
index db4adc50..00000000
--- a/openstack_dashboard/dashboards/admin/groups/constants.py
+++ /dev/null
@@ -1,11 +0,0 @@
-GROUPS_INDEX_URL = 'horizon:admin:groups:index'
-GROUPS_INDEX_VIEW_TEMPLATE = 'admin/groups/index.html'
-GROUPS_CREATE_URL = 'horizon:admin:groups:create'
-GROUPS_CREATE_VIEW_TEMPLATE = 'admin/groups/create.html'
-GROUPS_UPDATE_URL = 'horizon:admin:groups:update'
-GROUPS_UPDATE_VIEW_TEMPLATE = 'admin/groups/update.html'
-GROUPS_MANAGE_URL = 'horizon:admin:groups:manage_members'
-GROUPS_MANAGE_VIEW_TEMPLATE = 'admin/groups/manage.html'
-GROUPS_ADD_MEMBER_URL = 'horizon:admin:groups:add_members'
-GROUPS_ADD_MEMBER_VIEW_TEMPLATE = 'admin/groups/add_non_member.html'
-GROUPS_ADD_MEMBER_AJAX_VIEW_TEMPLATE = 'admin/groups/_add_non_member.html'
diff --git a/openstack_dashboard/dashboards/admin/groups/forms.py b/openstack_dashboard/dashboards/admin/groups/forms.py
deleted file mode 100644
index cdbdaded..00000000
--- a/openstack_dashboard/dashboards/admin/groups/forms.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Hewlett-Packard Development Company, L.P.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateGroupForm(forms.SelfHandlingForm):
- name = forms.CharField(label=_("Name"),
- required=True)
- description = forms.CharField(widget=forms.widgets.Textarea(),
- label=_("Description"),
- required=False)
-
- def handle(self, request, data):
- try:
- LOG.info('Creating group with name "%s"' % data['name'])
- domain_context = request.session.get('domain_context', None)
- api.keystone.group_create(
- request,
- domain_id=domain_context,
- name=data['name'],
- description=data['description'])
- messages.success(request,
- _('Group "%s" was successfully created.')
- % data['name'])
- except:
- exceptions.handle(request, _('Unable to create group.'))
- return False
- return True
-
-
-class UpdateGroupForm(forms.SelfHandlingForm):
- group_id = forms.CharField(widget=forms.HiddenInput())
- name = forms.CharField(label=_("Name"),
- required=True)
- description = forms.CharField(widget=forms.widgets.Textarea(),
- label=_("Description"),
- required=False)
-
- def handle(self, request, data):
- group_id = data.pop('group_id')
-
- try:
- api.keystone.group_update(request,
- group_id=group_id,
- name=data['name'],
- description=data['description'])
- messages.success(request,
- _('Group has been updated successfully.'))
- except:
- exceptions.handle(request, _('Unable to update the group.'))
- return False
- return True
diff --git a/openstack_dashboard/dashboards/admin/groups/panel.py b/openstack_dashboard/dashboards/admin/groups/panel.py
deleted file mode 100644
index 92452a6d..00000000
--- a/openstack_dashboard/dashboards/admin/groups/panel.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.api.keystone import VERSIONS as IDENTITY_VERSIONS
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Groups(horizon.Panel):
- name = _("Groups")
- slug = 'groups'
-
-
-if IDENTITY_VERSIONS.active >= 3:
- dashboard.Admin.register(Groups)
diff --git a/openstack_dashboard/dashboards/admin/groups/tables.py b/openstack_dashboard/dashboards/admin/groups/tables.py
deleted file mode 100644
index 9d2a1417..00000000
--- a/openstack_dashboard/dashboards/admin/groups/tables.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Hewlett-Packard Development Company, L.P.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.template import defaultfilters
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_ADD_MEMBER_URL
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_CREATE_URL
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_MANAGE_URL
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_UPDATE_URL
-
-
-LOG = logging.getLogger(__name__)
-LOGOUT_URL = 'logout'
-STATUS_CHOICES = (
- ("true", True),
- ("false", False)
-)
-
-
-class CreateGroupLink(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Group")
- url = GROUPS_CREATE_URL
- classes = ("ajax-modal", "btn-create")
-
- def allowed(self, request, group):
- return api.keystone.keystone_can_edit_group()
-
-
-class EditGroupLink(tables.LinkAction):
- name = "edit"
- verbose_name = _("Edit Group")
- url = GROUPS_UPDATE_URL
- classes = ("ajax-modal", "btn-edit")
-
- def allowed(self, request, group):
- return api.keystone.keystone_can_edit_group()
-
-
-class DeleteGroupsAction(tables.DeleteAction):
- name = "delete"
- data_type_singular = _("Group")
- data_type_plural = _("Groups")
-
- def allowed(self, request, datum):
- return api.keystone.keystone_can_edit_group()
-
- def delete(self, request, obj_id):
- LOG.info('Deleting group "%s".' % obj_id)
- api.keystone.group_delete(request, obj_id)
-
-
-class ManageUsersLink(tables.LinkAction):
- name = "users"
- verbose_name = _("Modify Users")
- url = GROUPS_MANAGE_URL
- classes = ("btn-edit")
-
- def allowed(self, request, datum):
- return api.keystone.keystone_can_edit_group()
-
-
-class GroupFilterAction(tables.FilterAction):
- def filter(self, table, groups, filter_string):
- """ Naive case-insensitive search """
- q = filter_string.lower()
-
- def comp(group):
- if q in group.name.lower():
- return True
- return False
-
- return filter(comp, groups)
-
-
-class GroupsTable(tables.DataTable):
- name = tables.Column('name', verbose_name=_('Name'))
- description = tables.Column(lambda obj: getattr(obj, 'description', None),
- verbose_name=_('Description'))
- id = tables.Column('id', verbose_name=_('Group ID'))
-
- class Meta:
- name = "groups"
- verbose_name = _("Groups")
- row_actions = (ManageUsersLink, EditGroupLink, DeleteGroupsAction)
- table_actions = (GroupFilterAction, CreateGroupLink,
- DeleteGroupsAction)
-
-
-class UserFilterAction(tables.FilterAction):
- def filter(self, table, users, filter_string):
- """ Naive case-insensitive search """
- q = filter_string.lower()
- return [user for user in users
- if q in user.name.lower()
- or q in user.email.lower()]
-
-
-class RemoveMembers(tables.DeleteAction):
- name = "removeGroupMember"
- action_present = _("Remove")
- action_past = _("Removed")
- data_type_singular = _("User")
- data_type_plural = _("Users")
-
- def allowed(self, request, user=None):
- return api.keystone.keystone_can_edit_group()
-
- def action(self, request, obj_id):
- user_obj = self.table.get_object_by_id(obj_id)
- group_id = self.table.kwargs['group_id']
- LOG.info('Removing user %s from group %s.' % (user_obj.id,
- group_id))
- api.keystone.remove_group_user(request,
- group_id=group_id,
- user_id=user_obj.id)
- # TODO(lin-hua-cheng): Fix the bug when removing current user
- # Keystone revokes the token of the user removed from the group.
- # If the logon user was removed, redirect the user to logout.
-
-
-class AddMembersLink(tables.LinkAction):
- name = "add_user_link"
- verbose_name = _("Add...")
- classes = ("ajax-modal", "btn-create")
- url = GROUPS_ADD_MEMBER_URL
-
- def allowed(self, request, user=None):
- return api.keystone.keystone_can_edit_group()
-
- def get_link_url(self, datum=None):
- return reverse(self.url, kwargs=self.table.kwargs)
-
-
-class UsersTable(tables.DataTable):
- name = tables.Column('name', verbose_name=_('User Name'))
- email = tables.Column('email', verbose_name=_('Email'),
- filters=[defaultfilters.urlize])
- id = tables.Column('id', verbose_name=_('User ID'))
- enabled = tables.Column('enabled', verbose_name=_('Enabled'),
- status=True,
- status_choices=STATUS_CHOICES,
- empty_value="False")
-
-
-class GroupMembersTable(UsersTable):
- class Meta:
- name = "group_members"
- verbose_name = _("Group Members")
- table_actions = (UserFilterAction, AddMembersLink, RemoveMembers)
-
-
-class AddMembers(tables.BatchAction):
- name = "addMember"
- action_present = _("Add")
- action_past = _("Added")
- data_type_singular = _("User")
- data_type_plural = _("Users")
- classes = ("btn-create", )
- requires_input = True
- success_url = GROUPS_MANAGE_URL
-
- def allowed(self, request, user=None):
- return api.keystone.keystone_can_edit_group()
-
- def action(self, request, obj_id):
- user_obj = self.table.get_object_by_id(obj_id)
- group_id = self.table.kwargs['group_id']
- LOG.info('Adding user %s to group %s.' % (user_obj.id,
- group_id))
- api.keystone.add_group_user(request,
- group_id=group_id,
- user_id=user_obj.id)
- # TODO(lin-hua-cheng): Fix the bug when adding current user
- # Keystone revokes the token of the user added to the group.
- # If the logon user was added, redirect the user to logout.
-
- def get_success_url(self, request=None):
- group_id = self.table.kwargs.get('group_id', None)
- return reverse(self.success_url, args=[group_id])
-
-
-class GroupNonMembersTable(UsersTable):
- class Meta:
- name = "group_non_members"
- verbose_name = _("Non-Members")
- table_actions = (UserFilterAction, AddMembers)
diff --git a/openstack_dashboard/dashboards/admin/groups/templates/groups/_add_non_member.html b/openstack_dashboard/dashboards/admin/groups/templates/groups/_add_non_member.html
deleted file mode 100644
index 360045ad..00000000
--- a/openstack_dashboard/dashboards/admin/groups/templates/groups/_add_non_member.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends "horizon/common/_modal_form_add_members.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block modal-header %}{% trans "Add Group Assignment" %}{% endblock %}
-
-{% block modal-footer %}
- <a href="{% url 'horizon:admin:groups:manage_members' group.id %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/groups/templates/groups/_create.html b/openstack_dashboard/dashboards/admin/groups/templates/groups/_create.html
deleted file mode 100644
index 5b4c3df6..00000000
--- a/openstack_dashboard/dashboards/admin/groups/templates/groups/_create.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_group_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:groups:create' %}{% endblock %}
-
-{% block modal-header %}{% trans "Create Group" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can create a new group to organize users and roles." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Group" %}" />
- <a href="{% url 'horizon:admin:groups:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/groups/templates/groups/_update.html b/openstack_dashboard/dashboards/admin/groups/templates/groups/_update.html
deleted file mode 100644
index 6ad94e32..00000000
--- a/openstack_dashboard/dashboards/admin/groups/templates/groups/_update.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_group_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:groups:update' group.id %}{% endblock %}
-
-{% block modal-header %}{% trans "Update Group" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can edit the group's details." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Update Group" %}" />
- <a href="{% url 'horizon:admin:groups:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/groups/templates/groups/add_non_member.html b/openstack_dashboard/dashboards/admin/groups/templates/groups/add_non_member.html
deleted file mode 100644
index fe380dbe..00000000
--- a/openstack_dashboard/dashboards/admin/groups/templates/groups/add_non_member.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans 'Add User to Group' %}{% endblock %}
-
-{% block main %}
- {% include 'admin/groups/_add_non_member.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/groups/templates/groups/create.html b/openstack_dashboard/dashboards/admin/groups/templates/groups/create.html
deleted file mode 100644
index 126c8aa6..00000000
--- a/openstack_dashboard/dashboards/admin/groups/templates/groups/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Group" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create Group") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/groups/_create.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/groups/templates/groups/index.html b/openstack_dashboard/dashboards/admin/groups/templates/groups/index.html
deleted file mode 100644
index 1c45b9d3..00000000
--- a/openstack_dashboard/dashboards/admin/groups/templates/groups/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Groups" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_domain_page_header.html" with title=_("Groups") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/groups/templates/groups/manage.html b/openstack_dashboard/dashboards/admin/groups/templates/groups/manage.html
deleted file mode 100644
index 5e8b778e..00000000
--- a/openstack_dashboard/dashboards/admin/groups/templates/groups/manage.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans 'Group Management' %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Group Management: ")|add:group.name %}
-{% endblock page_header %}
-
-{% block main %}
- {{ group_members_table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/groups/templates/groups/update.html b/openstack_dashboard/dashboards/admin/groups/templates/groups/update.html
deleted file mode 100644
index abb88a43..00000000
--- a/openstack_dashboard/dashboards/admin/groups/templates/groups/update.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Update Group" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Update Group") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/groups/_update.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/groups/tests.py b/openstack_dashboard/dashboards/admin/groups/tests.py
deleted file mode 100644
index 2bb59105..00000000
--- a/openstack_dashboard/dashboards/admin/groups/tests.py
+++ /dev/null
@@ -1,237 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IgnoreArg
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_ADD_MEMBER_URL as add_member_url
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_CREATE_URL as create_url
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_INDEX_URL as index_url
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_INDEX_VIEW_TEMPLATE
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_MANAGE_URL as manage_url
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_MANAGE_VIEW_TEMPLATE
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_UPDATE_URL as update_url
-
-
-GROUPS_INDEX_URL = reverse(index_url)
-GROUP_CREATE_URL = reverse(create_url)
-GROUP_UPDATE_URL = reverse(update_url, args=[1])
-GROUP_MANAGE_URL = reverse(manage_url, args=[1])
-GROUP_ADD_MEMBER_URL = reverse(add_member_url, args=[1])
-
-
-class GroupsViewTests(test.BaseAdminViewTests):
- def _get_domain_id(self):
- return self.request.session.get('domain_context', None)
-
- def _get_groups(self, domain_id):
- if not domain_id:
- groups = self.groups.list()
- else:
- groups = [group for group in self.groups.list()
- if group.domain_id == domain_id]
- return groups
-
- @test.create_stubs({api.keystone: ('group_list',)})
- def test_index(self):
- domain_id = self._get_domain_id()
- groups = self._get_groups(domain_id)
-
- api.keystone.group_list(IgnoreArg()).AndReturn(groups)
-
- self.mox.ReplayAll()
-
- res = self.client.get(GROUPS_INDEX_URL)
-
- self.assertTemplateUsed(res, GROUPS_INDEX_VIEW_TEMPLATE)
- self.assertItemsEqual(res.context['table'].data, groups)
- if domain_id:
- for group in res.context['table'].data:
- self.assertItemsEqual(group.domain_id, domain_id)
-
- self.assertContains(res, 'Create Group')
- self.assertContains(res, 'Edit')
- self.assertContains(res, 'Delete Group')
-
- def test_index_with_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_index()
-
- @test.create_stubs({api.keystone: ('group_list',
- 'keystone_can_edit_group')})
- def test_index_with_keystone_can_edit_group_false(self):
- domain_id = self._get_domain_id()
- groups = self._get_groups(domain_id)
-
- api.keystone.group_list(IgnoreArg()).AndReturn(groups)
- api.keystone.keystone_can_edit_group() \
- .MultipleTimes().AndReturn(False)
-
- self.mox.ReplayAll()
-
- res = self.client.get(GROUPS_INDEX_URL)
-
- self.assertTemplateUsed(res, GROUPS_INDEX_VIEW_TEMPLATE)
- self.assertItemsEqual(res.context['table'].data, groups)
-
- self.assertNotContains(res, 'Create Group')
- self.assertNotContains(res, 'Edit')
- self.assertNotContains(res, 'Delete Group')
-
- @test.create_stubs({api.keystone: ('group_create', )})
- def test_create(self):
- domain_id = self._get_domain_id()
- group = self.groups.get(id="1")
-
- api.keystone.group_create(IsA(http.HttpRequest),
- description=group.description,
- domain_id=domain_id,
- name=group.name).AndReturn(group)
-
- self.mox.ReplayAll()
-
- formData = {'method': 'CreateGroupForm',
- 'name': group.name,
- 'description': group.description}
- res = self.client.post(GROUP_CREATE_URL, formData)
-
- self.assertNoFormErrors(res)
- self.assertMessageCount(success=1)
-
- def test_create_with_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_create()
-
- @test.create_stubs({api.keystone: ('group_get',
- 'group_update')})
- def test_update(self):
- group = self.groups.get(id="1")
- test_description = 'updated description'
-
- api.keystone.group_get(IsA(http.HttpRequest), '1').AndReturn(group)
- api.keystone.group_update(IsA(http.HttpRequest),
- description=test_description,
- group_id=group.id,
- name=group.name).AndReturn(None)
-
- self.mox.ReplayAll()
-
- formData = {'method': 'UpdateGroupForm',
- 'group_id': group.id,
- 'name': group.name,
- 'description': test_description}
-
- res = self.client.post(GROUP_UPDATE_URL, formData)
-
- self.assertNoFormErrors(res)
-
- @test.create_stubs({api.keystone: ('group_list',
- 'group_delete')})
- def test_delete_group(self):
- group = self.groups.get(id="2")
-
- api.keystone.group_list(IgnoreArg()).AndReturn(self.groups.list())
- api.keystone.group_delete(IgnoreArg(), group.id)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'groups__delete__%s' % group.id}
- res = self.client.post(GROUPS_INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, GROUPS_INDEX_URL)
-
- @test.create_stubs({api.keystone: ('group_get',
- 'user_list',)})
- def test_manage(self):
- group = self.groups.get(id="1")
- group_members = self.users.list()
-
- api.keystone.group_get(IsA(http.HttpRequest), group.id).\
- AndReturn(group)
- api.keystone.user_list(IgnoreArg(),
- group=group.id).\
- AndReturn(group_members)
- self.mox.ReplayAll()
-
- res = self.client.get(GROUP_MANAGE_URL)
-
- self.assertTemplateUsed(res, GROUPS_MANAGE_VIEW_TEMPLATE)
- self.assertItemsEqual(res.context['table'].data, group_members)
-
- @test.create_stubs({api.keystone: ('user_list',
- 'remove_group_user')})
- def test_remove_user(self):
- group = self.groups.get(id="1")
- user = self.users.get(id="2")
-
- api.keystone.user_list(IgnoreArg(),
- group=group.id).\
- AndReturn(self.users.list())
- api.keystone.remove_group_user(IgnoreArg(),
- group_id=group.id,
- user_id=user.id)
- self.mox.ReplayAll()
-
- formData = {'action': 'group_members__removeGroupMember__%s' % user.id}
- res = self.client.post(GROUP_MANAGE_URL, formData)
-
- self.assertRedirectsNoFollow(res, GROUP_MANAGE_URL)
- self.assertMessageCount(success=1)
-
- @test.create_stubs({api.keystone: ('group_get',
- 'user_list',
- 'add_group_user')})
- def test_add_user(self):
- group = self.groups.get(id="1")
- user = self.users.get(id="2")
-
- api.keystone.group_get(IsA(http.HttpRequest), group.id).\
- AndReturn(group)
- api.keystone.user_list(IgnoreArg(),
- domain=group.domain_id).\
- AndReturn(self.users.list())
- api.keystone.user_list(IgnoreArg(),
- group=group.id).\
- AndReturn(self.users.list()[2:])
-
- api.keystone.add_group_user(IgnoreArg(),
- group_id=group.id,
- user_id=user.id)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'group_non_members__addMember__%s' % user.id}
- res = self.client.post(GROUP_ADD_MEMBER_URL, formData)
-
- self.assertRedirectsNoFollow(res, GROUP_MANAGE_URL)
- self.assertMessageCount(success=1)
diff --git a/openstack_dashboard/dashboards/admin/groups/urls.py b/openstack_dashboard/dashboards/admin/groups/urls.py
deleted file mode 100644
index 56b7e4f4..00000000
--- a/openstack_dashboard/dashboards/admin/groups/urls.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.groups.views import CreateView
-from openstack_dashboard.dashboards.admin.groups.views import IndexView
-from openstack_dashboard.dashboards.admin.groups.views import ManageMembersView
-from openstack_dashboard.dashboards.admin.groups.views import NonMembersView
-from openstack_dashboard.dashboards.admin.groups.views import UpdateView
-
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^create$', CreateView.as_view(), name='create'),
- url(r'^(?P<group_id>[^/]+)/update/$',
- UpdateView.as_view(), name='update'),
- url(r'^(?P<group_id>[^/]+)/manage_members/$',
- ManageMembersView.as_view(), name='manage_members'),
- url(r'^(?P<group_id>[^/]+)/add_members/$',
- NonMembersView.as_view(), name='add_members'),
-)
diff --git a/openstack_dashboard/dashboards/admin/groups/views.py b/openstack_dashboard/dashboards/admin/groups/views.py
deleted file mode 100644
index db2ad7e9..00000000
--- a/openstack_dashboard/dashboards/admin/groups/views.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_ADD_MEMBER_AJAX_VIEW_TEMPLATE
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_ADD_MEMBER_VIEW_TEMPLATE
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_CREATE_VIEW_TEMPLATE
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_INDEX_URL
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_INDEX_VIEW_TEMPLATE
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_MANAGE_VIEW_TEMPLATE
-from openstack_dashboard.dashboards.admin.groups.constants \
- import GROUPS_UPDATE_VIEW_TEMPLATE
-from openstack_dashboard.dashboards.admin.groups.forms import CreateGroupForm
-from openstack_dashboard.dashboards.admin.groups.forms import UpdateGroupForm
-from openstack_dashboard.dashboards.admin.groups.tables \
- import GroupMembersTable
-from openstack_dashboard.dashboards.admin.groups.tables \
- import GroupNonMembersTable
-from openstack_dashboard.dashboards.admin.groups.tables import GroupsTable
-
-
-class IndexView(tables.DataTableView):
- table_class = GroupsTable
- template_name = GROUPS_INDEX_VIEW_TEMPLATE
-
- def get_data(self):
- groups = []
- domain_context = self.request.session.get('domain_context', None)
- try:
- # TODO(dklyle): once keystoneclient supports filtering by
- # domain change this to use that cleaner method
- groups = api.keystone.group_list(self.request)
- if domain_context:
- domain_groups = []
- for group in groups:
- if group.domain_id == domain_context:
- domain_groups.append(group)
- groups = domain_groups
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve group list.'))
- return groups
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateGroupForm
- template_name = GROUPS_CREATE_VIEW_TEMPLATE
- success_url = reverse_lazy(GROUPS_INDEX_URL)
-
-
-class UpdateView(forms.ModalFormView):
- form_class = UpdateGroupForm
- template_name = GROUPS_UPDATE_VIEW_TEMPLATE
- success_url = reverse_lazy(GROUPS_INDEX_URL)
-
- def get_object(self):
- if not hasattr(self, "_object"):
- try:
- self._object = api.keystone.group_get(self.request,
- self.kwargs['group_id'])
- except:
- redirect = reverse(GROUPS_INDEX_URL)
- exceptions.handle(self.request,
- _('Unable to update group.'),
- redirect=redirect)
- return self._object
-
- def get_context_data(self, **kwargs):
- context = super(UpdateView, self).get_context_data(**kwargs)
- context['group'] = self.get_object()
- return context
-
- def get_initial(self):
- group = self.get_object()
- return {'group_id': group.id,
- 'name': group.name,
- 'description': group.description}
-
-
-class GroupManageMixin(object):
- def _get_group(self):
- if not hasattr(self, "_group"):
- group_id = self.kwargs['group_id']
- self._group = api.keystone.group_get(self.request, group_id)
- return self._group
-
- def _get_group_members(self):
- if not hasattr(self, "_group_members"):
- group_id = self.kwargs['group_id']
- self._group_members = api.keystone.user_list(self.request,
- group=group_id)
- return self._group_members
-
- def _get_group_non_members(self):
- if not hasattr(self, "_group_non_members"):
- domain_id = self._get_group().domain_id
- all_users = api.keystone.user_list(self.request,
- domain=domain_id)
- group_members = self._get_group_members()
- group_member_ids = [user.id for user in group_members]
- self._group_non_members = filter(
- lambda u: u.id not in group_member_ids, all_users)
- return self._group_non_members
-
-
-class ManageMembersView(GroupManageMixin, tables.DataTableView):
- table_class = GroupMembersTable
- template_name = GROUPS_MANAGE_VIEW_TEMPLATE
-
- def get_context_data(self, **kwargs):
- context = super(ManageMembersView, self).get_context_data(**kwargs)
- context['group'] = self._get_group()
- return context
-
- def get_data(self):
- group_members = []
- try:
- group_members = self._get_group_members()
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve group users.'))
- return group_members
-
-
-class NonMembersView(GroupManageMixin, forms.ModalFormMixin,
- tables.DataTableView):
- template_name = GROUPS_ADD_MEMBER_VIEW_TEMPLATE
- ajax_template_name = GROUPS_ADD_MEMBER_AJAX_VIEW_TEMPLATE
- table_class = GroupNonMembersTable
-
- def get_context_data(self, **kwargs):
- context = super(NonMembersView, self).get_context_data(**kwargs)
- context['group'] = self._get_group()
- return context
-
- def get_data(self):
- group_non_members = []
- try:
- group_non_members = self._get_group_non_members()
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve users.'))
- return group_non_members
diff --git a/openstack_dashboard/dashboards/admin/hypervisors/__init__.py b/openstack_dashboard/dashboards/admin/hypervisors/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/hypervisors/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/hypervisors/panel.py b/openstack_dashboard/dashboards/admin/hypervisors/panel.py
deleted file mode 100644
index 156702ef..00000000
--- a/openstack_dashboard/dashboards/admin/hypervisors/panel.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 B1 Systems GmbH
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.dashboards.admin import dashboard
-
-
-class Hypervisors(horizon.Panel):
- name = _("Hypervisors")
- slug = 'hypervisors'
- permissions = ('openstack.roles.admin',)
-
-
-dashboard.Admin.register(Hypervisors)
diff --git a/openstack_dashboard/dashboards/admin/hypervisors/tables.py b/openstack_dashboard/dashboards/admin/hypervisors/tables.py
deleted file mode 100644
index 8562434b..00000000
--- a/openstack_dashboard/dashboards/admin/hypervisors/tables.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 B1 Systems GmbH
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-from horizon import tables
-
-LOG = logging.getLogger(__name__)
-
-
-def get_memory(hypervisor):
- return _("%s MB") % hypervisor.memory_mb
-
-
-def get_memory_used(hypervisor):
- return _("%s MB") % hypervisor.memory_mb_used
-
-
-def get_local(hypervisor):
- return _("%s GB") % hypervisor.local_gb
-
-
-def get_local_used(hypervisor):
- return _("%s GB") % hypervisor.local_gb_used
-
-
-class AdminHypervisorsTable(tables.DataTable):
- hypervisor_hostname = tables.Column("hypervisor_hostname",
- verbose_name=_("Hostname"))
-
- hypervisor_type = tables.Column("hypervisor_type",
- verbose_name=_("Type"))
-
- vcpus = tables.Column("vcpus",
- verbose_name=_("VCPUs (total)"))
-
- vcpus_used = tables.Column("vcpus_used",
- verbose_name=_("VCPUs (used)"))
-
- memory = tables.Column(get_memory,
- verbose_name=_("RAM (total)"),
- attrs={'data-type': 'size'})
-
- memory_used = tables.Column(get_memory_used,
- verbose_name=_("RAM (used)"),
- attrs={'data-type': 'size'})
-
- local = tables.Column(get_local,
- verbose_name=_("Storage (total)"),
- attrs={'data-type': 'size'})
-
- local_used = tables.Column(get_local_used,
- verbose_name=_("Storage (used)"),
- attrs={'data-type': 'size'})
-
- running_vms = tables.Column("running_vms",
- verbose_name=_("Instances"))
-
- class Meta:
- name = "hypervisors"
- verbose_name = _("Hypervisors")
diff --git a/openstack_dashboard/dashboards/admin/hypervisors/templates/hypervisors/index.html b/openstack_dashboard/dashboards/admin/hypervisors/templates/hypervisors/index.html
deleted file mode 100644
index c5bda9c0..00000000
--- a/openstack_dashboard/dashboards/admin/hypervisors/templates/hypervisors/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Hypervisors" %}{% endblock %}
-
-{% block page_header %}
-{% include "horizon/common/_page_header.html" with title=_("All Hypervisors") %}
-{% endblock page_header %}
-
-{% block main %}
-{{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/hypervisors/tests.py b/openstack_dashboard/dashboards/admin/hypervisors/tests.py
deleted file mode 100644
index dfa81443..00000000
--- a/openstack_dashboard/dashboards/admin/hypervisors/tests.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 B1 Systems GmbH
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.core.urlresolvers import reverse
-from django import http
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class HypervisorViewTest(test.BaseAdminViewTests):
- @test.create_stubs({api.nova: ('hypervisor_list',)})
- def test_index(self):
- hypervisors = self.hypervisors.list()
- api.nova.hypervisor_list(IsA(http.HttpRequest)).AndReturn(hypervisors)
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:hypervisors:index'))
- self.assertTemplateUsed(res, 'admin/hypervisors/index.html')
- self.assertItemsEqual(res.context['table'].data, hypervisors)
diff --git a/openstack_dashboard/dashboards/admin/hypervisors/urls.py b/openstack_dashboard/dashboards/admin/hypervisors/urls.py
deleted file mode 100644
index a47c123f..00000000
--- a/openstack_dashboard/dashboards/admin/hypervisors/urls.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 B1 Systems GmbH
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.hypervisors.views \
- import AdminIndexView
-
-
-urlpatterns = patterns(
- 'openstack_dashboard.dashboards.admin.hypervisors.views',
- url(r'^$', AdminIndexView.as_view(), name='index')
-)
diff --git a/openstack_dashboard/dashboards/admin/hypervisors/views.py b/openstack_dashboard/dashboards/admin/hypervisors/views.py
deleted file mode 100644
index ad3cc6f7..00000000
--- a/openstack_dashboard/dashboards/admin/hypervisors/views.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 B1 Systems GmbH
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.admin.hypervisors.tables import \
- AdminHypervisorsTable
-
-LOG = logging.getLogger(__name__)
-
-
-class AdminIndexView(tables.DataTableView):
- table_class = AdminHypervisorsTable
- template_name = 'admin/hypervisors/index.html'
-
- def get_data(self):
- hypervisors = []
- try:
- hypervisors = api.nova.hypervisor_list(self.request)
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve hypervisor list.'))
-
- return hypervisors
diff --git a/openstack_dashboard/dashboards/admin/images/__init__.py b/openstack_dashboard/dashboards/admin/images/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/images/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/images/forms.py b/openstack_dashboard/dashboards/admin/images/forms.py
deleted file mode 100644
index 944813d8..00000000
--- a/openstack_dashboard/dashboards/admin/images/forms.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from openstack_dashboard.dashboards.project.images_and_snapshots \
- .images import forms
-
-
-class AdminCreateImageForm(forms.CreateImageForm):
- pass
-
-
-class AdminUpdateImageForm(forms.UpdateImageForm):
- pass
diff --git a/openstack_dashboard/dashboards/admin/images/panel.py b/openstack_dashboard/dashboards/admin/images/panel.py
deleted file mode 100644
index aa8d354d..00000000
--- a/openstack_dashboard/dashboards/admin/images/panel.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Images(horizon.Panel):
- name = _("Images")
- slug = 'images'
-
-
-dashboard.Admin.register(Images)
diff --git a/openstack_dashboard/dashboards/admin/images/tables.py b/openstack_dashboard/dashboards/admin/images/tables.py
deleted file mode 100644
index 3ccd3314..00000000
--- a/openstack_dashboard/dashboards/admin/images/tables.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-from openstack_dashboard.dashboards.project.images_and_snapshots \
- .images.tables import CreateImage
-from openstack_dashboard.dashboards.project.images_and_snapshots \
- .images.tables import DeleteImage
-from openstack_dashboard.dashboards.project.images_and_snapshots \
- .images.tables import EditImage
-from openstack_dashboard.dashboards.project.images_and_snapshots \
- .images.tables import ImagesTable
-
-
-class AdminCreateImage(CreateImage):
- url = "horizon:admin:images:create"
-
-
-class AdminDeleteImage(DeleteImage):
- def allowed(self, request, image=None):
- if image and image.protected:
- return False
- else:
- return True
-
-
-class AdminEditImage(EditImage):
- url = "horizon:admin:images:update"
-
- def allowed(self, request, image=None):
- return True
-
-
-class AdminImagesTable(ImagesTable):
- name = tables.Column("name",
- link="horizon:admin:images:detail",
- verbose_name=_("Image Name"))
-
- class Meta:
- name = "images"
- verbose_name = _("Images")
- table_actions = (AdminCreateImage, AdminDeleteImage)
- row_actions = (AdminEditImage, AdminDeleteImage)
diff --git a/openstack_dashboard/dashboards/admin/images/templates/images/_create.html b/openstack_dashboard/dashboards/admin/images/templates/images/_create.html
deleted file mode 100644
index ecdd0d39..00000000
--- a/openstack_dashboard/dashboards/admin/images/templates/images/_create.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_image_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:images:create' %}{% endblock %}
-{% block form_attrs %}enctype="multipart/form-data"{% endblock %}
-
-{% block modal-header %}{% trans "Create An Image" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>
- {% trans "Specify an image to upload to the Image Service." %}
- </p>
- <p>
- {% trans "Currently only images available via an HTTP URL are supported. The image location must be accessible to the Image Service. Compressed image binaries are supported (.zip and .tar.gz.)" %}
- </p>
- <p>
- <strong>{% trans "Please note: " %}</strong>
- {% trans "The Image Location field MUST be a valid and direct URL to the image binary. URLs that redirect or serve error pages will result in unusable images." %}
- </p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Image" %}" />
- <a href="{% url 'horizon:admin:images:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/images/templates/images/_update.html b/openstack_dashboard/dashboards/admin/images/templates/images/_update.html
deleted file mode 100644
index 7fa462d8..00000000
--- a/openstack_dashboard/dashboards/admin/images/templates/images/_update.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_image_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:images:update' image.id %}{% endblock %}
-
-{% block modal_id %}update_image_modal{% endblock %}
-{% block modal-header %}{% trans "Update Image" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can modify different properties of an image." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Update Image" %}" />
- <a href="{% url 'horizon:admin:images:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/images/templates/images/create.html b/openstack_dashboard/dashboards/admin/images/templates/images/create.html
deleted file mode 100644
index dbd5ef7c..00000000
--- a/openstack_dashboard/dashboards/admin/images/templates/images/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create An Image" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create An Image") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/images/_create.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/images/templates/images/index.html b/openstack_dashboard/dashboards/admin/images/templates/images/index.html
deleted file mode 100644
index b82d3377..00000000
--- a/openstack_dashboard/dashboards/admin/images/templates/images/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Images" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Images") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/images/templates/images/update.html b/openstack_dashboard/dashboards/admin/images/templates/images/update.html
deleted file mode 100644
index e81c679b..00000000
--- a/openstack_dashboard/dashboards/admin/images/templates/images/update.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-
-{% block title %}{% trans "Update Image" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Update Image") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/images/_update.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/images/tests.py b/openstack_dashboard/dashboards/admin/images/tests.py
deleted file mode 100644
index 07aa378d..00000000
--- a/openstack_dashboard/dashboards/admin/images/tests.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf import settings
-from django.core.urlresolvers import reverse
-from django import http
-from django.test.utils import override_settings
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-from openstack_dashboard.dashboards.admin.images.tables import AdminImagesTable
-
-
-class ImageCreateViewTest(test.BaseAdminViewTests):
- def test_admin_image_create_view_uses_admin_template(self):
- res = self.client.get(
- reverse('horizon:admin:images:create'))
- self.assertTemplateUsed(res, 'admin/images/create.html')
-
-
-class ImagesViewTest(test.BaseAdminViewTests):
- @test.create_stubs({api.glance: ('image_list_detailed',)})
- def test_images_list(self):
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- marker=None,
- paginate=True) \
- .AndReturn([self.images.list(),
- False])
- self.mox.ReplayAll()
-
- res = self.client.get(
- reverse('horizon:admin:images:index'))
- self.assertTemplateUsed(res, 'admin/images/index.html')
- self.assertEqual(len(res.context['images_table'].data),
- len(self.images.list()))
-
- @override_settings(API_RESULT_PAGE_SIZE=2)
- @test.create_stubs({api.glance: ('image_list_detailed',)})
- def test_images_list_get_pagination(self):
- images = self.images.list()[:5]
-
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- marker=None,
- paginate=True) \
- .AndReturn([images,
- True])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- marker=None,
- paginate=True) \
- .AndReturn([images[:2],
- True])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- marker=images[2].id,
- paginate=True) \
- .AndReturn([images[2:4],
- True])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- marker=images[4].id,
- paginate=True) \
- .AndReturn([images[4:],
- True])
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:images:index')
- res = self.client.get(url)
- # get all
- self.assertEqual(len(res.context['images_table'].data),
- len(images))
- self.assertTemplateUsed(res, 'admin/images/index.html')
-
- res = self.client.get(url)
- # get first page with 2 items
- self.assertEqual(len(res.context['images_table'].data),
- settings.API_RESULT_PAGE_SIZE)
-
- url = "?".join([reverse('horizon:admin:images:index'),
- "=".join([AdminImagesTable._meta.pagination_param,
- images[2].id])])
- res = self.client.get(url)
- # get second page (items 2-4)
- self.assertEqual(len(res.context['images_table'].data),
- settings.API_RESULT_PAGE_SIZE)
-
- url = "?".join([reverse('horizon:admin:images:index'),
- "=".join([AdminImagesTable._meta.pagination_param,
- images[4].id])])
- res = self.client.get(url)
- # get third page (item 5)
- self.assertEqual(len(res.context['images_table'].data),
- 1)
diff --git a/openstack_dashboard/dashboards/admin/images/urls.py b/openstack_dashboard/dashboards/admin/images/urls.py
deleted file mode 100644
index 89766290..00000000
--- a/openstack_dashboard/dashboards/admin/images/urls.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.images.views import CreateView
-from openstack_dashboard.dashboards.admin.images.views import DetailView
-from openstack_dashboard.dashboards.admin.images.views import IndexView
-from openstack_dashboard.dashboards.admin.images.views import UpdateView
-
-
-urlpatterns = patterns('openstack_dashboard.dashboards.admin.images.views',
- url(r'^images/$', IndexView.as_view(), name='index'),
- url(r'^create/$', CreateView.as_view(), name='create'),
- url(r'^(?P<image_id>[^/]+)/update/$', UpdateView.as_view(), name='update'),
- url(r'^(?P<image_id>[^/]+)/detail/$', DetailView.as_view(), name='detail')
-)
diff --git a/openstack_dashboard/dashboards/admin/images/views.py b/openstack_dashboard/dashboards/admin/images/views.py
deleted file mode 100644
index 5c3b4c56..00000000
--- a/openstack_dashboard/dashboards/admin/images/views.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project \
- .images_and_snapshots.images import views
-
-from openstack_dashboard.dashboards.admin.images.forms \
- import AdminCreateImageForm
-from openstack_dashboard.dashboards.admin.images.forms \
- import AdminUpdateImageForm
-from openstack_dashboard.dashboards.admin.images.tables \
- import AdminImagesTable
-
-
-LOG = logging.getLogger(__name__)
-
-
-class IndexView(tables.DataTableView):
- table_class = AdminImagesTable
- template_name = 'admin/images/index.html'
-
- def has_more_data(self, table):
- return self._more
-
- def get_data(self):
- images = []
- marker = self.request.GET.get(AdminImagesTable._meta.pagination_param,
- None)
- try:
- images, self._more = api.glance.image_list_detailed(self.request,
- marker=marker,
- paginate=True)
- except:
- self._more = False
- msg = _('Unable to retrieve image list.')
- exceptions.handle(self.request, msg)
- return images
-
-
-class CreateView(views.CreateView):
- template_name = 'admin/images/create.html'
- form_class = AdminCreateImageForm
- success_url = reverse_lazy('horizon:admin:images:index')
-
-
-class UpdateView(views.UpdateView):
- template_name = 'admin/images/update.html'
- form_class = AdminUpdateImageForm
- success_url = reverse_lazy('horizon:admin:images:index')
-
-
-class DetailView(views.DetailView):
- """ Admin placeholder for image detail view. """
- pass
diff --git a/openstack_dashboard/dashboards/admin/info/__init__.py b/openstack_dashboard/dashboards/admin/info/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/info/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/info/panel.py b/openstack_dashboard/dashboards/admin/info/panel.py
deleted file mode 100644
index 6c0508cc..00000000
--- a/openstack_dashboard/dashboards/admin/info/panel.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Quotas(horizon.Panel):
- name = _("System Info")
- slug = 'info'
-
-
-dashboard.Admin.register(Quotas)
diff --git a/openstack_dashboard/dashboards/admin/info/tables.py b/openstack_dashboard/dashboards/admin/info/tables.py
deleted file mode 100644
index 56a3cabb..00000000
--- a/openstack_dashboard/dashboards/admin/info/tables.py
+++ /dev/null
@@ -1,121 +0,0 @@
-import logging
-
-from django import template
-from django.template.defaultfilters import timesince
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-from horizon.utils.filters import parse_isotime
-
-
-LOG = logging.getLogger(__name__)
-
-
-class QuotaFilterAction(tables.FilterAction):
- def filter(self, table, tenants, filter_string):
- q = filter_string.lower()
-
- def comp(tenant):
- if q in tenant.name.lower():
- return True
- return False
-
- return filter(comp, tenants)
-
-
-def get_quota_name(quota):
- if quota.name == "cores":
- return _('VCPUs')
- if quota.name == "floating_ips":
- return _('Floating IPs')
- return quota.name.replace("_", " ").title()
-
-
-class QuotasTable(tables.DataTable):
- name = tables.Column(get_quota_name, verbose_name=_('Quota Name'))
- limit = tables.Column("limit", verbose_name=_('Limit'))
-
- def get_object_id(self, obj):
- return obj.name
-
- class Meta:
- name = "quotas"
- verbose_name = _("Quotas")
- table_actions = (QuotaFilterAction,)
- multi_select = False
-
-
-class ServiceFilterAction(tables.FilterAction):
- def filter(self, table, services, filter_string):
- q = filter_string.lower()
-
- def comp(service):
- if q in service.type.lower():
- return True
- return False
-
- return filter(comp, services)
-
-
-def get_stats(service):
- return template.loader.render_to_string('admin/services/_stats.html',
- {'service': service})
-
-
-def get_enabled(service, reverse=False):
- options = ["Enabled", "Disabled"]
- if reverse:
- options.reverse()
- # if not configured in this region, neither option makes sense
- if service.host:
- return options[0] if not service.disabled else options[1]
- return None
-
-
-class ServicesTable(tables.DataTable):
- id = tables.Column('id', verbose_name=_('Id'), hidden=True)
- name = tables.Column("name", verbose_name=_('Name'))
- service_type = tables.Column('__unicode__', verbose_name=_('Service'))
- host = tables.Column('host', verbose_name=_('Host'))
- enabled = tables.Column(get_enabled,
- verbose_name=_('Enabled'),
- status=True)
-
- class Meta:
- name = "services"
- verbose_name = _("Services")
- table_actions = (ServiceFilterAction,)
- multi_select = False
- status_columns = ["enabled"]
-
-
-class NovaServiceFilterAction(tables.FilterAction):
- def filter(self, table, services, filter_string):
- q = filter_string.lower()
-
- def comp(service):
- if q in service.type.lower():
- return True
- return False
-
- return filter(comp, services)
-
-
-class NovaServicesTable(tables.DataTable):
- binary = tables.Column("binary", verbose_name=_('Name'))
- host = tables.Column('host', verbose_name=_('Host'))
- zone = tables.Column('zone', verbose_name=_('Zone'))
- status = tables.Column('status', verbose_name=_('Status'))
- state = tables.Column('state', verbose_name=_('State'))
- updated_at = tables.Column('updated_at',
- verbose_name=_('Updated At'),
- filters=(parse_isotime, timesince))
-
- def get_object_id(self, obj):
- return "%s-%s-%s" % (obj.binary, obj.host, obj.zone)
-
- class Meta:
- name = "nova_services"
- verbose_name = _("Compute Services")
- table_actions = (NovaServiceFilterAction,)
- multi_select = False
diff --git a/openstack_dashboard/dashboards/admin/info/tabs.py b/openstack_dashboard/dashboards/admin/info/tabs.py
deleted file mode 100644
index 0c9649be..00000000
--- a/openstack_dashboard/dashboards/admin/info/tabs.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-
-from openstack_dashboard.api import keystone
-from openstack_dashboard.api import nova
-from openstack_dashboard.usage import quotas
-
-from openstack_dashboard.dashboards.admin.info.tables import NovaServicesTable
-from openstack_dashboard.dashboards.admin.info.tables import QuotasTable
-from openstack_dashboard.dashboards.admin.info.tables import ServicesTable
-
-
-class DefaultQuotasTab(tabs.TableTab):
- table_classes = (QuotasTable,)
- name = _("Default Quotas")
- slug = "quotas"
- template_name = ("horizon/common/_detail_table.html")
-
- def get_quotas_data(self):
- request = self.tab_group.request
- try:
- quota_set = quotas.get_default_quota_data(request)
- data = quota_set.items
- except:
- data = []
- exceptions.handle(self.request, _('Unable to get quota info.'))
- return data
-
-
-class ServicesTab(tabs.TableTab):
- table_classes = (ServicesTable,)
- name = _("Services")
- slug = "services"
- template_name = ("horizon/common/_detail_table.html")
-
- def get_services_data(self):
- request = self.tab_group.request
- services = []
- for i, service in enumerate(request.user.service_catalog):
- service['id'] = i
- services.append(
- keystone.Service(service, request.user.services_region))
- return services
-
-
-class NovaServicesTab(tabs.TableTab):
- table_classes = (NovaServicesTable,)
- name = _("Compute Services")
- slug = "nova_services"
- template_name = ("horizon/common/_detail_table.html")
-
- def get_nova_services_data(self):
- try:
- services = nova.service_list(self.tab_group.request)
- except Exception:
- services = []
- msg = _('Unable to get nova services list.')
- exceptions.check_message(["Connection", "refused"], msg)
- raise
-
- return services
-
-
-class SystemInfoTabs(tabs.TabGroup):
- slug = "system_info"
- tabs = (ServicesTab, NovaServicesTab, DefaultQuotasTab,)
- sticky = True
diff --git a/openstack_dashboard/dashboards/admin/info/templates/info/index.html b/openstack_dashboard/dashboards/admin/info/templates/info/index.html
deleted file mode 100644
index a947ae38..00000000
--- a/openstack_dashboard/dashboards/admin/info/templates/info/index.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "System Info" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("System Info")%}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/info/tests.py b/openstack_dashboard/dashboards/admin/info/tests.py
deleted file mode 100644
index 79cd383e..00000000
--- a/openstack_dashboard/dashboards/admin/info/tests.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django import http
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-INDEX_URL = reverse('horizon:admin:info:index')
-
-
-class ServicesViewTests(test.BaseAdminViewTests):
- @test.create_stubs({api.nova: ('service_list',)})
- def test_index(self):
- self.mox.StubOutWithMock(api.nova, 'default_quota_get')
- self.mox.StubOutWithMock(api.cinder, 'default_quota_get')
- api.nova.default_quota_get(IsA(http.HttpRequest),
- self.tenant.id).AndReturn(self.quotas.nova)
- api.cinder.default_quota_get(IsA(http.HttpRequest), self.tenant.id) \
- .AndReturn(self.cinder_quotas.first())
- services = self.services.list()
- api.nova.service_list(IsA(http.HttpRequest)).AndReturn(services)
-
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
-
- self.assertTemplateUsed(res, 'admin/info/index.html')
-
- services_tab = res.context['tab_group'].get_tab('services')
- self.assertQuerysetEqual(services_tab._tables['services'].data,
- ['<Service: compute>',
- '<Service: volume>',
- '<Service: image>',
- '<Service: identity (native backend)>',
- '<Service: object-store>',
- '<Service: network>',
- '<Service: ec2>',
- '<Service: orchestration>'])
-
- quotas_tab = res.context['tab_group'].get_tab('quotas')
- self.assertQuerysetEqual(quotas_tab._tables['quotas'].data,
- ['<Quota: (injected_file_content_bytes, 1)>',
- '<Quota: (metadata_items, 1)>',
- '<Quota: (injected_files, 1)>',
- '<Quota: (gigabytes, 1000)>',
- '<Quota: (ram, 10000)>',
- '<Quota: (floating_ips, 1)>',
- '<Quota: (fixed_ips, 10)>',
- '<Quota: (instances, 10)>',
- '<Quota: (snapshots, 1)>',
- '<Quota: (volumes, 1)>',
- '<Quota: (cores, 10)>',
- '<Quota: (security_groups, 10)>',
- '<Quota: (security_group_rules, 20)>'],
- ordered=False)
diff --git a/openstack_dashboard/dashboards/admin/info/urls.py b/openstack_dashboard/dashboards/admin/info/urls.py
deleted file mode 100644
index 8509abdb..00000000
--- a/openstack_dashboard/dashboards/admin/info/urls.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.info.views import IndexView
-
-
-urlpatterns = patterns('openstack_dashboard.dashboards.admin.info.views',
- url(r'^$', IndexView.as_view(), name='index'))
diff --git a/openstack_dashboard/dashboards/admin/info/views.py b/openstack_dashboard/dashboards/admin/info/views.py
deleted file mode 100644
index 3dd1e2e7..00000000
--- a/openstack_dashboard/dashboards/admin/info/views.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from horizon import tabs
-
-from openstack_dashboard.dashboards.admin.info.tabs import SystemInfoTabs
-
-
-LOG = logging.getLogger(__name__)
-
-
-class IndexView(tabs.TabbedTableView):
- tab_group_class = SystemInfoTabs
- template_name = 'admin/info/index.html'
diff --git a/openstack_dashboard/dashboards/admin/instances/__init__.py b/openstack_dashboard/dashboards/admin/instances/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/instances/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/instances/panel.py b/openstack_dashboard/dashboards/admin/instances/panel.py
deleted file mode 100644
index 3e4fd511..00000000
--- a/openstack_dashboard/dashboards/admin/instances/panel.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Instances(horizon.Panel):
- name = _("Instances")
- slug = 'instances'
- permissions = ('openstack.roles.admin',)
-
-
-dashboard.Admin.register(Instances)
diff --git a/openstack_dashboard/dashboards/admin/instances/tables.py b/openstack_dashboard/dashboards/admin/instances/tables.py
deleted file mode 100644
index 265a9529..00000000
--- a/openstack_dashboard/dashboards/admin/instances/tables.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Openstack, LLC
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.template.defaultfilters import timesince
-from django.template.defaultfilters import title
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-from horizon.utils.filters import parse_isotime
-from horizon.utils.filters import replace_underscores
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.instances.tables import \
- ACTIVE_STATES
-from openstack_dashboard.dashboards.project.instances.tables import \
- ConfirmResize
-from openstack_dashboard.dashboards.project.instances.tables import \
- ConsoleLink
-from openstack_dashboard.dashboards.project.instances.tables import \
- CreateSnapshot
-from openstack_dashboard.dashboards.project.instances.tables import \
- EditInstance
-from openstack_dashboard.dashboards.project.instances.tables import \
- get_ips
-from openstack_dashboard.dashboards.project.instances.tables import \
- get_power_state
-from openstack_dashboard.dashboards.project.instances.tables import \
- get_size
-from openstack_dashboard.dashboards.project.instances.tables import \
- is_deleting
-from openstack_dashboard.dashboards.project.instances.tables import \
- LogLink
-from openstack_dashboard.dashboards.project.instances.tables import \
- RebootInstance
-from openstack_dashboard.dashboards.project.instances.tables import \
- RevertResize
-from openstack_dashboard.dashboards.project.instances.tables import \
- SoftRebootInstance
-from openstack_dashboard.dashboards.project.instances.tables import \
- STATUS_DISPLAY_CHOICES
-from openstack_dashboard.dashboards.project.instances.tables import \
- TASK_DISPLAY_CHOICES
-from openstack_dashboard.dashboards.project.instances.tables import \
- TerminateInstance
-from openstack_dashboard.dashboards.project.instances.tables import \
- TogglePause
-from openstack_dashboard.dashboards.project.instances.tables import \
- ToggleSuspend
-from openstack_dashboard.dashboards.project.instances.tables import \
- UpdateRow
-LOG = logging.getLogger(__name__)
-
-
-class AdminEditInstance(EditInstance):
- url = "horizon:admin:instances:update"
-
-
-class MigrateInstance(tables.BatchAction):
- name = "migrate"
- action_present = _("Migrate")
- action_past = _("Scheduled migration (pending confirmation) of")
- data_type_singular = _("Instance")
- data_type_plural = _("Instances")
- classes = ("btn-migrate", "btn-danger")
-
- def allowed(self, request, instance):
- return ((instance.status in ACTIVE_STATES
- or instance.status == 'SHUTOFF')
- and not is_deleting(instance))
-
- def action(self, request, obj_id):
- api.nova.server_migrate(request, obj_id)
-
-
-class AdminUpdateRow(UpdateRow):
- def get_data(self, request, instance_id):
- instance = super(AdminUpdateRow, self).get_data(request, instance_id)
- tenant = api.keystone.tenant_get(request,
- instance.tenant_id,
- admin=True)
- instance.tenant_name = getattr(tenant, "name", None)
- return instance
-
-
-class AdminInstanceFilterAction(tables.FilterAction):
- def filter(self, table, instances, filter_string):
- """ Naive case-insensitive search. """
- q = filter_string.lower()
- return [instance for instance in instances
- if q in instance.name.lower()]
-
-
-class AdminInstancesTable(tables.DataTable):
- TASK_STATUS_CHOICES = (
- (None, True),
- ("none", True)
- )
- STATUS_CHOICES = (
- ("active", True),
- ("shutoff", True),
- ("suspended", True),
- ("paused", True),
- ("error", False),
- )
- tenant = tables.Column("tenant_name", verbose_name=_("Project"))
- # NOTE(gabriel): Commenting out the user column because all we have
- # is an ID, and correlating that at production scale using our current
- # techniques isn't practical. It can be added back in when we have names
- # returned in a practical manner by the API.
- #user = tables.Column("user_id", verbose_name=_("User"))
- host = tables.Column("OS-EXT-SRV-ATTR:host",
- verbose_name=_("Host"),
- classes=('nowrap-col',))
- name = tables.Column("name",
- link=("horizon:admin:instances:detail"),
- verbose_name=_("Name"))
- image_name = tables.Column("image_name",
- verbose_name=_("Image Name"))
- ip = tables.Column(get_ips,
- verbose_name=_("IP Address"),
- attrs={'data-type': "ip"})
- size = tables.Column(get_size,
- verbose_name=_("Size"),
- classes=('nowrap-col',),
- attrs={'data-type': 'size'})
- status = tables.Column("status",
- filters=(title, replace_underscores),
- verbose_name=_("Status"),
- status=True,
- status_choices=STATUS_CHOICES,
- display_choices=STATUS_DISPLAY_CHOICES)
- task = tables.Column("OS-EXT-STS:task_state",
- verbose_name=_("Task"),
- filters=(title, replace_underscores),
- status=True,
- status_choices=TASK_STATUS_CHOICES,
- display_choices=TASK_DISPLAY_CHOICES)
- state = tables.Column(get_power_state,
- filters=(title, replace_underscores),
- verbose_name=_("Power State"))
- created = tables.Column("created",
- verbose_name=_("Uptime"),
- filters=(parse_isotime, timesince))
-
- class Meta:
- name = "instances"
- verbose_name = _("Instances")
- status_columns = ["status", "task"]
- table_actions = (TerminateInstance, AdminInstanceFilterAction)
- row_class = AdminUpdateRow
- row_actions = (ConfirmResize, RevertResize, AdminEditInstance,
- ConsoleLink, LogLink, CreateSnapshot, TogglePause,
- ToggleSuspend, MigrateInstance, SoftRebootInstance,
- RebootInstance, TerminateInstance)
diff --git a/openstack_dashboard/dashboards/admin/instances/templates/instances/index.html b/openstack_dashboard/dashboards/admin/instances/templates/instances/index.html
deleted file mode 100644
index 43f9d1c9..00000000
--- a/openstack_dashboard/dashboards/admin/instances/templates/instances/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Instances" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("All Instances") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/instances/tests.py b/openstack_dashboard/dashboards/admin/instances/tests.py
deleted file mode 100644
index be2373fa..00000000
--- a/openstack_dashboard/dashboards/admin/instances/tests.py
+++ /dev/null
@@ -1,208 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import uuid
-
-from django.core.urlresolvers import reverse
-from django import http
-from django.utils.datastructures import SortedDict
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class InstanceViewTest(test.BaseAdminViewTests):
- @test.create_stubs({api.nova: ('flavor_list', 'server_list',
- 'extension_supported',),
- api.keystone: ('tenant_list',)})
- def test_index(self):
- servers = self.servers.list()
- flavors = self.flavors.list()
- tenants = self.tenants.list()
- api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.keystone.tenant_list(IsA(http.HttpRequest)).\
- AndReturn([tenants, False])
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest),
- all_tenants=True, search_opts=search_opts) \
- .AndReturn([servers, False])
- api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(flavors)
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:instances:index'))
- self.assertTemplateUsed(res, 'admin/instances/index.html')
- instances = res.context['table'].data
- self.assertItemsEqual(instances, servers)
-
- @test.create_stubs({api.nova: ('flavor_list', 'flavor_get',
- 'server_list', 'extension_supported',),
- api.keystone: ('tenant_list',)})
- def test_index_flavor_list_exception(self):
- servers = self.servers.list()
- tenants = self.tenants.list()
- flavors = self.flavors.list()
- full_flavors = SortedDict([(f.id, f) for f in flavors])
-
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest),
- all_tenants=True, search_opts=search_opts) \
- .AndReturn([servers, False])
- api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)). \
- AndRaise(self.exceptions.nova)
- api.keystone.tenant_list(IsA(http.HttpRequest)).\
- AndReturn([tenants, False])
- for server in servers:
- api.nova.flavor_get(IsA(http.HttpRequest), server.flavor["id"]). \
- AndReturn(full_flavors[server.flavor["id"]])
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:instances:index'))
- self.assertTemplateUsed(res, 'admin/instances/index.html')
- instances = res.context['table'].data
- self.assertItemsEqual(instances, servers)
-
- @test.create_stubs({api.nova: ('flavor_list', 'flavor_get',
- 'server_list', 'extension_supported', ),
- api.keystone: ('tenant_list',)})
- def test_index_flavor_get_exception(self):
- servers = self.servers.list()
- flavors = self.flavors.list()
- tenants = self.tenants.list()
- # UUIDs generated using indexes are unlikely to match
- # any of existing flavor ids and are guaranteed to be deterministic.
- for i, server in enumerate(servers):
- server.flavor['id'] = str(uuid.UUID(int=i))
-
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest),
- all_tenants=True, search_opts=search_opts) \
- .AndReturn([servers, False])
- api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)). \
- AndReturn(flavors)
- api.keystone.tenant_list(IsA(http.HttpRequest)).\
- AndReturn([tenants, False])
- for server in servers:
- api.nova.flavor_get(IsA(http.HttpRequest), server.flavor["id"]). \
- AndRaise(self.exceptions.nova)
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:instances:index'))
- instances = res.context['table'].data
- self.assertTemplateUsed(res, 'admin/instances/index.html')
- self.assertMessageCount(res, error=len(servers))
- self.assertItemsEqual(instances, servers)
-
- @test.create_stubs({api.nova: ('server_list',)})
- def test_index_server_list_exception(self):
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest),
- all_tenants=True, search_opts=search_opts) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:instances:index'))
- self.assertTemplateUsed(res, 'admin/instances/index.html')
- self.assertEqual(len(res.context['instances_table'].data), 0)
-
- @test.create_stubs({api.nova: ('server_get', 'flavor_get',
- 'extension_supported', ),
- api.keystone: ('tenant_get',)})
- def test_ajax_loading_instances(self):
- server = self.servers.first()
- flavor = self.flavors.list()[0]
- tenant = self.tenants.list()[0]
-
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
- api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_get(IsA(http.HttpRequest),
- server.flavor['id']).AndReturn(flavor)
- api.keystone.tenant_get(IsA(http.HttpRequest),
- server.tenant_id,
- admin=True).AndReturn(tenant)
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:instances:index') + \
- "?action=row_update&table=instances&obj_id=" + server.id
-
- res = self.client.get(url, {},
- HTTP_X_REQUESTED_WITH='XMLHttpRequest')
- self.assertTemplateUsed(res, "horizon/common/_data_table_row.html")
-
- self.assertContains(res, "test_tenant", 1, 200)
- self.assertContains(res, "instance-host", 1, 200)
- # two instances of name, other name comes from row data-display
- self.assertContains(res, "server_1", 2, 200)
- self.assertContains(res, "10.0.0.1", 1, 200)
- self.assertContains(res, "512MB RAM | 1 VCPU | 0 Disk", 1, 200)
- self.assertContains(res, "Active", 1, 200)
- self.assertContains(res, "Running", 1, 200)
-
- @test.create_stubs({api.nova: ('flavor_list', 'server_list',
- 'extension_supported', ),
- api.keystone: ('tenant_list',)})
- def test_index_options_before_migrate(self):
- api.keystone.tenant_list(IsA(http.HttpRequest)).\
- AndReturn([self.tenants.list(), False])
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest),
- all_tenants=True, search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)).\
- AndReturn(self.flavors.list())
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:instances:index'))
- self.assertContains(res, "instances__migrate")
- self.assertNotContains(res, "instances__confirm")
- self.assertNotContains(res, "instances__revert")
-
- @test.create_stubs({api.nova: ('flavor_list', 'server_list',
- 'extension_supported', ),
- api.keystone: ('tenant_list',)})
- def test_index_options_after_migrate(self):
- servers = self.servers.list()
- server1 = servers[0]
- server1.status = "VERIFY_RESIZE"
- server2 = servers[2]
- server2.status = "VERIFY_RESIZE"
- api.keystone.tenant_list(IsA(http.HttpRequest)) \
- .AndReturn([self.tenants.list(), False])
- search_opts = {'marker': None, 'paginate': True}
- api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.server_list(IsA(http.HttpRequest),
- all_tenants=True, search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.flavor_list(IsA(http.HttpRequest)).\
- AndReturn(self.flavors.list())
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:instances:index'))
- self.assertContains(res, "instances__confirm")
- self.assertContains(res, "instances__revert")
- self.assertNotContains(res, "instances__migrate")
diff --git a/openstack_dashboard/dashboards/admin/instances/urls.py b/openstack_dashboard/dashboards/admin/instances/urls.py
deleted file mode 100644
index 58f4816c..00000000
--- a/openstack_dashboard/dashboards/admin/instances/urls.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.instances.views import AdminIndexView
-from openstack_dashboard.dashboards.admin.instances.views \
- import AdminUpdateView
-from openstack_dashboard.dashboards.project.instances.views \
- import DetailView
-
-
-INSTANCES = r'^(?P<instance_id>[^/]+)/%s$'
-
-
-urlpatterns = patterns('openstack_dashboard.dashboards.admin.instances.views',
- url(r'^$', AdminIndexView.as_view(), name='index'),
- url(INSTANCES % 'update', AdminUpdateView.as_view(), name='update'),
- url(INSTANCES % 'detail', DetailView.as_view(), name='detail'),
- url(INSTANCES % 'console', 'console', name='console'),
- url(INSTANCES % 'vnc', 'vnc', name='vnc'),
- url(INSTANCES % 'spice', 'spice', name='spice'),
-)
diff --git a/openstack_dashboard/dashboards/admin/instances/views.py b/openstack_dashboard/dashboards/admin/instances/views.py
deleted file mode 100644
index 253f35a0..00000000
--- a/openstack_dashboard/dashboards/admin/instances/views.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Openstack, LLC
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.datastructures import SortedDict
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.admin.instances.tables import \
- AdminInstancesTable
-from openstack_dashboard.dashboards.project.instances.views import \
- console as p_console
-from openstack_dashboard.dashboards.project.instances.views import \
- spice as p_spice
-from openstack_dashboard.dashboards.project.instances.views import \
- UpdateView
-from openstack_dashboard.dashboards.project.instances.views import \
- vnc as p_vnc
-from openstack_dashboard.dashboards.project.instances.workflows.\
- update_instance import AdminUpdateInstance
-
-LOG = logging.getLogger(__name__)
-
-
-# re-use console from project.instances.views to make reflection work
-def console(args, **kvargs):
- return p_console(args, **kvargs)
-
-
-# re-use vnc from project.instances.views to make reflection work
-def vnc(args, **kvargs):
- return p_vnc(args, **kvargs)
-
-
-# re-use spice from project.instances.views to make reflection work
-def spice(args, **kvargs):
- return p_spice(args, **kvargs)
-
-
-class AdminUpdateView(UpdateView):
- workflow_class = AdminUpdateInstance
-
-
-class AdminIndexView(tables.DataTableView):
- table_class = AdminInstancesTable
- template_name = 'admin/instances/index.html'
-
- def has_more_data(self, table):
- return self._more
-
- def get_data(self):
- instances = []
- marker = self.request.GET.get(
- AdminInstancesTable._meta.pagination_param, None)
- try:
- instances, self._more = api.nova.server_list(
- self.request,
- search_opts={'marker': marker,
- 'paginate': True},
- all_tenants=True)
- except:
- self._more = False
- exceptions.handle(self.request,
- _('Unable to retrieve instance list.'))
- if instances:
- # Gather our flavors to correlate against IDs
- try:
- flavors = api.nova.flavor_list(self.request)
- except:
- # If fails to retrieve flavor list, creates an empty list.
- flavors = []
-
- # Gather our tenants to correlate against IDs
- try:
- tenants, has_more = api.keystone.tenant_list(self.request)
- except:
- tenants = []
- msg = _('Unable to retrieve instance project information.')
- exceptions.handle(self.request, msg)
-
- full_flavors = SortedDict([(f.id, f) for f in flavors])
- tenant_dict = SortedDict([(t.id, t) for t in tenants])
- # Loop through instances to get flavor and tenant info.
- for inst in instances:
- flavor_id = inst.flavor["id"]
- try:
- if flavor_id in full_flavors:
- inst.full_flavor = full_flavors[flavor_id]
- else:
- # If the flavor_id is not in full_flavors list,
- # gets it via nova api.
- inst.full_flavor = api.nova.flavor_get(
- self.request, flavor_id)
- except:
- msg = _('Unable to retrieve instance size information.')
- exceptions.handle(self.request, msg)
- tenant = tenant_dict.get(inst.tenant_id, None)
- inst.tenant_name = getattr(tenant, "name", None)
- return instances
diff --git a/openstack_dashboard/dashboards/admin/models.py b/openstack_dashboard/dashboards/admin/models.py
deleted file mode 100644
index 6313a32f..00000000
--- a/openstack_dashboard/dashboards/admin/models.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/openstack_dashboard/dashboards/admin/networks/__init__.py b/openstack_dashboard/dashboards/admin/networks/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/networks/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/networks/forms.py b/openstack_dashboard/dashboards/admin/networks/forms.py
deleted file mode 100644
index 318f5688..00000000
--- a/openstack_dashboard/dashboards/admin/networks/forms.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateNetwork(forms.SelfHandlingForm):
- name = forms.CharField(max_length=255,
- label=_("Name"),
- required=False)
- tenant_id = forms.ChoiceField(label=_("Project"))
- admin_state = forms.BooleanField(label=_("Admin State"),
- initial=True, required=False)
- shared = forms.BooleanField(label=_("Shared"),
- initial=False, required=False)
- external = forms.BooleanField(label=_("External Network"),
- initial=False, required=False)
-
- @classmethod
- def _instantiate(cls, request, *args, **kwargs):
- return cls(request, *args, **kwargs)
-
- def __init__(self, request, *args, **kwargs):
- super(CreateNetwork, self).__init__(request, *args, **kwargs)
- tenant_choices = [('', _("Select a project"))]
- tenants, has_more = api.keystone.tenant_list(request)
- for tenant in tenants:
- if tenant.enabled:
- tenant_choices.append((tenant.id, tenant.name))
- self.fields['tenant_id'].choices = tenant_choices
-
- def handle(self, request, data):
- try:
- params = {'name': data['name'],
- 'tenant_id': data['tenant_id'],
- 'admin_state_up': data['admin_state'],
- 'shared': data['shared'],
- 'router:external': data['external']}
- network = api.neutron.network_create(request, **params)
- msg = _('Network %s was successfully created.') % data['name']
- LOG.debug(msg)
- messages.success(request, msg)
- return network
- except:
- redirect = reverse('horizon:admin:networks:index')
- msg = _('Failed to create network %s') % data['name']
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class UpdateNetwork(forms.SelfHandlingForm):
- name = forms.CharField(label=_("Name"), required=False)
- tenant_id = forms.CharField(widget=forms.HiddenInput)
- network_id = forms.CharField(label=_("ID"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- admin_state = forms.BooleanField(label=_("Admin State"), required=False)
- shared = forms.BooleanField(label=_("Shared"), required=False)
- external = forms.BooleanField(label=_("External Network"), required=False)
- failure_url = 'horizon:admin:networks:index'
-
- def handle(self, request, data):
- try:
- params = {'name': data['name'],
- 'admin_state_up': data['admin_state'],
- 'shared': data['shared'],
- 'router:external': data['external']}
- network = api.neutron.network_modify(request, data['network_id'],
- **params)
- msg = _('Network %s was successfully updated.') % data['name']
- LOG.debug(msg)
- messages.success(request, msg)
- return network
- except:
- msg = _('Failed to update network %s') % data['name']
- LOG.info(msg)
- redirect = reverse(self.failure_url)
- exceptions.handle(request, msg, redirect=redirect)
diff --git a/openstack_dashboard/dashboards/admin/networks/panel.py b/openstack_dashboard/dashboards/admin/networks/panel.py
deleted file mode 100644
index 22774c6c..00000000
--- a/openstack_dashboard/dashboards/admin/networks/panel.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.dashboards.admin import dashboard
-
-
-class Networks(horizon.Panel):
- name = _("Networks")
- slug = 'networks'
- permissions = ('openstack.services.network',)
-
-dashboard.Admin.register(Networks)
diff --git a/openstack_dashboard/dashboards/admin/networks/ports/__init__.py b/openstack_dashboard/dashboards/admin/networks/ports/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/networks/ports/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/networks/ports/forms.py b/openstack_dashboard/dashboards/admin/networks/ports/forms.py
deleted file mode 100644
index bebe6464..00000000
--- a/openstack_dashboard/dashboards/admin/networks/ports/forms.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.networks.ports \
- import forms as project_forms
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreatePort(forms.SelfHandlingForm):
- network_name = forms.CharField(label=_("Network Name"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- network_id = forms.CharField(label=_("Network ID"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- name = forms.CharField(max_length=255,
- label=_("Name"),
- required=False)
- admin_state = forms.BooleanField(label=_("Admin State"),
- initial=True, required=False)
- device_id = forms.CharField(max_length=100, label=_("Device ID"),
- help_text='Device ID attached to the port',
- required=False)
- device_owner = forms.CharField(max_length=100, label=_("Device Owner"),
- help_text='Device owner attached to the port',
- required=False)
-
- def handle(self, request, data):
- try:
- # We must specify tenant_id of the network which a subnet is
- # created for if admin user does not belong to the tenant.
- network = api.neutron.network_get(request, data['network_id'])
- data['tenant_id'] = network.tenant_id
- data['admin_state_up'] = data['admin_state']
- del data['network_name']
- del data['admin_state']
-
- port = api.neutron.port_create(request, **data)
- msg = _('Port %s was successfully created.') % port['id']
- LOG.debug(msg)
- messages.success(request, msg)
- return port
- except:
- msg = _('Failed to create a port for network %s') \
- % data['network_id']
- LOG.info(msg)
- redirect = reverse('horizon:admin:networks:detail',
- args=(data['network_id'],))
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class UpdatePort(project_forms.UpdatePort):
- #tenant_id = forms.CharField(widget=forms.HiddenInput())
- device_id = forms.CharField(max_length=100, label=_("Device ID"),
- help_text='Device ID attached to the port',
- required=False)
- device_owner = forms.CharField(max_length=100, label=_("Device Owner"),
- help_text='Device owner attached to the port',
- required=False)
- failure_url = 'horizon:admin:networks:detail'
-
- def handle(self, request, data):
- try:
- LOG.debug('params = %s' % data)
- port = api.neutron.port_modify(request, data['port_id'],
- name=data['name'],
- admin_state_up=data['admin_state'],
- device_id=data['device_id'],
- device_owner=data['device_owner'])
- msg = _('Port %s was successfully updated.') % data['port_id']
- LOG.debug(msg)
- messages.success(request, msg)
- return port
- except Exception:
- msg = _('Failed to update port %s') % data['port_id']
- LOG.info(msg)
- redirect = reverse(self.failure_url,
- args=[data['network_id']])
- exceptions.handle(request, msg, redirect=redirect)
diff --git a/openstack_dashboard/dashboards/admin/networks/ports/tables.py b/openstack_dashboard/dashboards/admin/networks/ports/tables.py
deleted file mode 100644
index 7d5db780..00000000
--- a/openstack_dashboard/dashboards/admin/networks/ports/tables.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.networks.ports.tables import \
- get_attached
-from openstack_dashboard.dashboards.project.networks.ports.tables import \
- get_fixed_ips
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DeletePort(tables.DeleteAction):
- data_type_singular = _("Port")
- data_type_plural = _("Ports")
-
- def delete(self, request, obj_id):
- try:
- api.neutron.port_delete(request, obj_id)
- except:
- msg = _('Failed to delete subnet %s') % obj_id
- LOG.info(msg)
- network_id = self.table.kwargs['network_id']
- redirect = reverse('horizon:admin:networks:detail',
- args=[network_id])
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class CreatePort(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Port")
- url = "horizon:admin:networks:addport"
- classes = ("ajax-modal", "btn-create")
-
- def get_link_url(self, datum=None):
- network_id = self.table.kwargs['network_id']
- return reverse(self.url, args=(network_id,))
-
-
-class UpdatePort(tables.LinkAction):
- name = "update"
- verbose_name = _("Edit Port")
- url = "horizon:admin:networks:editport"
- classes = ("ajax-modal", "btn-edit")
-
- def get_link_url(self, port):
- network_id = self.table.kwargs['network_id']
- return reverse(self.url, args=(network_id, port.id))
-
-
-class PortsTable(tables.DataTable):
- name = tables.Column("name",
- verbose_name=_("Name"),
- link="horizon:admin:networks:ports:detail")
- fixed_ips = tables.Column(get_fixed_ips, verbose_name=_("Fixed IPs"))
- device_id = tables.Column(get_attached, verbose_name=_("Device Attached"))
- status = tables.Column("status", verbose_name=_("Status"))
- admin_state = tables.Column("admin_state",
- verbose_name=_("Admin State"))
-
- class Meta:
- name = "ports"
- verbose_name = _("Ports")
- table_actions = (CreatePort, DeletePort)
- row_actions = (UpdatePort, DeletePort,)
diff --git a/openstack_dashboard/dashboards/admin/networks/ports/tabs.py b/openstack_dashboard/dashboards/admin/networks/ports/tabs.py
deleted file mode 100644
index d9825809..00000000
--- a/openstack_dashboard/dashboards/admin/networks/ports/tabs.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "overview"
- template_name = "project/networks/ports/_detail_overview.html"
-
- def get_context_data(self, request):
- port_id = self.tab_group.kwargs['port_id']
- try:
- port = api.neutron.port_get(self.request, port_id)
- except:
- redirect = reverse('horizon:admin:networks:index')
- msg = _('Unable to retrieve port details.')
- exceptions.handle(request, msg, redirect=redirect)
- return {'port': port}
-
-
-class PortDetailTabs(tabs.TabGroup):
- slug = "port_details"
- tabs = (OverviewTab,)
diff --git a/openstack_dashboard/dashboards/admin/networks/ports/urls.py b/openstack_dashboard/dashboards/admin/networks/ports/urls.py
deleted file mode 100644
index c91ea6b9..00000000
--- a/openstack_dashboard/dashboards/admin/networks/ports/urls.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.networks.ports.views import \
- DetailView
-
-PORTS = r'^(?P<port_id>[^/]+)/%s$'
-VIEW_MOD = 'openstack_dashboard.dashboards.admin.networks.ports.views'
-
-
-urlpatterns = patterns(VIEW_MOD,
- url(PORTS % 'detail', DetailView.as_view(), name='detail')
-)
diff --git a/openstack_dashboard/dashboards/admin/networks/ports/views.py b/openstack_dashboard/dashboards/admin/networks/ports/views.py
deleted file mode 100644
index 60284d10..00000000
--- a/openstack_dashboard/dashboards/admin/networks/ports/views.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.networks.ports \
- import views as project_views
-
-from openstack_dashboard.dashboards.admin.networks.ports.forms \
- import CreatePort
-from openstack_dashboard.dashboards.admin.networks.ports.forms \
- import UpdatePort
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreatePort
- template_name = 'admin/networks/ports/create.html'
- success_url = 'horizon:admin:networks:detail'
- failure_url = 'horizon:admin:networks:detail'
-
- def get_success_url(self):
- return reverse(self.success_url,
- args=(self.kwargs['network_id'],))
-
- def get_object(self):
- if not hasattr(self, "_object"):
- try:
- network_id = self.kwargs["network_id"]
- self._object = api.neutron.network_get(self.request,
- network_id)
- except:
- redirect = reverse(self.failure_url,
- args=(self.kwargs['network_id'],))
- msg = _("Unable to retrieve network.")
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_context_data(self, **kwargs):
- context = super(CreateView, self).get_context_data(**kwargs)
- context['network'] = self.get_object()
- return context
-
- def get_initial(self):
- network = self.get_object()
- return {"network_id": self.kwargs['network_id'],
- "network_name": network.name}
-
-
-class UpdateView(project_views.UpdateView):
- form_class = UpdatePort
- template_name = 'admin/networks/ports/update.html'
- context_object_name = 'port'
- success_url = 'horizon:admin:networks:detail'
diff --git a/openstack_dashboard/dashboards/admin/networks/subnets/__init__.py b/openstack_dashboard/dashboards/admin/networks/subnets/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/networks/subnets/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/networks/subnets/tables.py b/openstack_dashboard/dashboards/admin/networks/subnets/tables.py
deleted file mode 100644
index be9aec0c..00000000
--- a/openstack_dashboard/dashboards/admin/networks/subnets/tables.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DeleteSubnet(tables.DeleteAction):
- data_type_singular = _("Subnet")
- data_type_plural = _("Subnets")
-
- def delete(self, request, obj_id):
- try:
- api.neutron.subnet_delete(request, obj_id)
- except:
- msg = _('Failed to delete subnet %s') % obj_id
- LOG.info(msg)
- network_id = self.table.kwargs['network_id']
- redirect = reverse('horizon:admin:networks:detail',
- args=[network_id])
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class CreateSubnet(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Subnet")
- url = "horizon:admin:networks:addsubnet"
- classes = ("ajax-modal", "btn-create")
-
- def get_link_url(self, datum=None):
- network_id = self.table.kwargs['network_id']
- return reverse(self.url, args=(network_id,))
-
-
-class UpdateSubnet(tables.LinkAction):
- name = "update"
- verbose_name = _("Edit Subnet")
- url = "horizon:admin:networks:editsubnet"
- classes = ("ajax-modal", "btn-edit")
-
- def get_link_url(self, subnet):
- network_id = self.table.kwargs['network_id']
- return reverse(self.url, args=(network_id, subnet.id))
-
-
-class SubnetsTable(tables.DataTable):
- name = tables.Column("name", verbose_name=_("Name"),
- link='horizon:admin:networks:subnets:detail')
- cidr = tables.Column("cidr", verbose_name=_("CIDR"))
- ip_version = tables.Column("ipver_str", verbose_name=_("IP Version"))
- gateway_ip = tables.Column("gateway_ip", verbose_name=_("Gateway IP"))
-
- def get_object_display(self, subnet):
- return subnet.id
-
- class Meta:
- name = "subnets"
- verbose_name = _("Subnets")
- table_actions = (CreateSubnet, DeleteSubnet)
- row_actions = (UpdateSubnet, DeleteSubnet,)
diff --git a/openstack_dashboard/dashboards/admin/networks/subnets/urls.py b/openstack_dashboard/dashboards/admin/networks/subnets/urls.py
deleted file mode 100644
index 3779372d..00000000
--- a/openstack_dashboard/dashboards/admin/networks/subnets/urls.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.networks.subnets.views import \
- DetailView
-
-
-SUBNETS = r'^(?P<subnet_id>[^/]+)/%s$'
-VIEW_MOD = 'openstack_dashboard.dashboards.admin.networks.subnets.views'
-
-
-urlpatterns = patterns(VIEW_MOD,
- url(SUBNETS % 'detail', DetailView.as_view(), name='detail')
-)
diff --git a/openstack_dashboard/dashboards/admin/networks/subnets/views.py b/openstack_dashboard/dashboards/admin/networks/subnets/views.py
deleted file mode 100644
index b802b1ac..00000000
--- a/openstack_dashboard/dashboards/admin/networks/subnets/views.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from openstack_dashboard.dashboards.project.networks.subnets \
- import views as project_views
-
-from openstack_dashboard.dashboards.admin.networks.subnets.workflows \
- import CreateSubnet
-from openstack_dashboard.dashboards.admin.networks.subnets.workflows \
- import UpdateSubnet
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateView(project_views.CreateView):
- workflow_class = CreateSubnet
-
-
-class UpdateView(project_views.UpdateView):
- workflow_class = UpdateSubnet
diff --git a/openstack_dashboard/dashboards/admin/networks/subnets/workflows.py b/openstack_dashboard/dashboards/admin/networks/subnets/workflows.py
deleted file mode 100644
index 2fab7b1e..00000000
--- a/openstack_dashboard/dashboards/admin/networks/subnets/workflows.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.networks.subnets \
- import workflows as project_workflows
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateSubnet(project_workflows.CreateSubnet):
- def get_success_url(self):
- return reverse("horizon:admin:networks:detail",
- args=(self.context.get('network_id'),))
-
- def get_failure_url(self):
- return reverse("horizon:admin:networks:detail",
- args=(self.context.get('network_id'),))
-
- def handle(self, request, data):
- try:
- # We must specify tenant_id of the network which a subnet is
- # created for if admin user does not belong to the tenant.
- network = api.neutron.network_get(request,
- self.context['network_id'])
- except:
- msg = (_('Failed to retrieve network %s for a subnet') %
- data['network_id'])
- LOG.info(msg)
- redirect = self.get_failure_url()
- exceptions.handle(request, msg, redirect=redirect)
- subnet = self._create_subnet(request, data,
- tenant_id=network.tenant_id)
- return True if subnet else False
-
-
-class UpdateSubnet(project_workflows.UpdateSubnet):
- success_url = "horizon:admin:networks:detail"
- failure_url = "horizon:admin:networks:detail"
diff --git a/openstack_dashboard/dashboards/admin/networks/tables.py b/openstack_dashboard/dashboards/admin/networks/tables.py
deleted file mode 100644
index 8b29c1c1..00000000
--- a/openstack_dashboard/dashboards/admin/networks/tables.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.template import defaultfilters as filters
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.networks.tables import get_subnets
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DeleteNetwork(tables.DeleteAction):
- data_type_singular = _("Network")
- data_type_plural = _("Networks")
-
- def delete(self, request, obj_id):
- try:
- api.neutron.network_delete(request, obj_id)
- except:
- msg = _('Failed to delete network %s') % obj_id
- LOG.info(msg)
- redirect = reverse('horizon:admin:networks:index')
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class CreateNetwork(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Network")
- url = "horizon:admin:networks:create"
- classes = ("ajax-modal", "btn-create")
-
-
-class EditNetwork(tables.LinkAction):
- name = "update"
- verbose_name = _("Edit Network")
- url = "horizon:admin:networks:update"
- classes = ("ajax-modal", "btn-edit")
-
-
-#def _get_subnets(network):
-# cidrs = [subnet.get('cidr') for subnet in network.subnets]
-# return ','.join(cidrs)
-
-
-class NetworksTable(tables.DataTable):
- tenant = tables.Column("tenant_name", verbose_name=_("Project"))
- name = tables.Column("name", verbose_name=_("Network Name"),
- link='horizon:admin:networks:detail')
- subnets = tables.Column(get_subnets,
- verbose_name=_("Subnets Associated"),)
- shared = tables.Column("shared", verbose_name=_("Shared"),
- filters=(filters.yesno, filters.capfirst))
- status = tables.Column("status", verbose_name=_("Status"))
- admin_state = tables.Column("admin_state",
- verbose_name=_("Admin State"))
-
- class Meta:
- name = "networks"
- verbose_name = _("Networks")
- table_actions = (CreateNetwork, DeleteNetwork)
- row_actions = (EditNetwork, DeleteNetwork)
diff --git a/openstack_dashboard/dashboards/admin/networks/templates/networks/_create.html b/openstack_dashboard/dashboards/admin/networks/templates/networks/_create.html
deleted file mode 100644
index 391848a6..00000000
--- a/openstack_dashboard/dashboards/admin/networks/templates/networks/_create.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_network_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:networks:create' %}{% endblock %}
-
-{% block modal_id %}create_network_modal{% endblock %}
-{% block modal-header %}{% trans "Create Network" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "Select a name for your network."%}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Network" %}" />
- <a href="{% url 'horizon:admin:networks:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/networks/templates/networks/_update.html b/openstack_dashboard/dashboards/admin/networks/templates/networks/_update.html
deleted file mode 100644
index 6c1c36ba..00000000
--- a/openstack_dashboard/dashboards/admin/networks/templates/networks/_update.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_network_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:networks:update' network_id %}{% endblock %}
-
-{% block modal-header %}{% trans "Edit Network" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "You may update the editable properties of your network here." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
- <a href="{% url 'horizon:admin:networks:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/networks/templates/networks/create.html b/openstack_dashboard/dashboards/admin/networks/templates/networks/create.html
deleted file mode 100644
index 975227f4..00000000
--- a/openstack_dashboard/dashboards/admin/networks/templates/networks/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Network" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create Network") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "admin/networks/_create.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/networks/templates/networks/index.html b/openstack_dashboard/dashboards/admin/networks/templates/networks/index.html
deleted file mode 100644
index bcb1b74f..00000000
--- a/openstack_dashboard/dashboards/admin/networks/templates/networks/index.html
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Networks" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Networks") %}
-{% endblock page_header %}
-
-{% block main %}
- <div id="networks">
- {{ networks_table.render }}
- </div>
-
- <div id="subnets">
- {{ subnets_table.render }}
- </div>
-
- <div id="ports">
- {{ ports_table.render }}
- </div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/_create.html b/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/_create.html
deleted file mode 100644
index 8f9e9493..00000000
--- a/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/_create.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_port_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:networks:addport' network.id %}
-{% endblock %}
-
-{% block modal-header %}{% trans "Create Port" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "You can create a port for the network. If you specify device ID to be attached, the device specified will be attached to the port created."%}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Port" %}" />
- <a href="{% url 'horizon:admin:networks:detail' network.id %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/_update.html b/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/_update.html
deleted file mode 100644
index 7c409171..00000000
--- a/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/_update.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_port_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:networks:editport' network_id port_id %}{% endblock %}
-
-{% block modal-header %}{% trans "Edit Port" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <dl>
- <dt>{% trans "ID" %}</dt>
- <dd>{{ port_id }}</dd>
- </dl>
- <hr>
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "You may update the editable properties of your port here." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
- <a href="{% url 'horizon:admin:networks:detail' network_id %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/create.html b/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/create.html
deleted file mode 100644
index e9955130..00000000
--- a/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Port" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create Port") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "admin/networks/ports/_create.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/update.html b/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/update.html
deleted file mode 100644
index ae0f91cf..00000000
--- a/openstack_dashboard/dashboards/admin/networks/templates/networks/ports/update.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Update Port" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Update Port") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/networks/ports/_update.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/networks/templates/networks/subnets/index.html b/openstack_dashboard/dashboards/admin/networks/templates/networks/subnets/index.html
deleted file mode 100644
index 9c25d565..00000000
--- a/openstack_dashboard/dashboards/admin/networks/templates/networks/subnets/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Network Detail" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Network Detail") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/networks/templates/networks/update.html b/openstack_dashboard/dashboards/admin/networks/templates/networks/update.html
deleted file mode 100644
index a70a0b1a..00000000
--- a/openstack_dashboard/dashboards/admin/networks/templates/networks/update.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Update Network" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Update Network") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/networks/_update.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/networks/tests.py b/openstack_dashboard/dashboards/admin/networks/tests.py
deleted file mode 100644
index 9a3eb4ff..00000000
--- a/openstack_dashboard/dashboards/admin/networks/tests.py
+++ /dev/null
@@ -1,822 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.core.urlresolvers import reverse
-from django import http
-
-from horizon.workflows.views import WorkflowView
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.networks.tests \
- import form_data_subnet
-from openstack_dashboard.test import helpers as test
-
-
-INDEX_URL = reverse('horizon:admin:networks:index')
-
-
-class NetworkTests(test.BaseAdminViewTests):
- @test.create_stubs({api.neutron: ('network_list',),
- api.keystone: ('tenant_list',)})
- def test_index(self):
- tenants = self.tenants.list()
- api.neutron.network_list(IsA(http.HttpRequest)) \
- .AndReturn(self.networks.list())
- api.keystone.tenant_list(IsA(http.HttpRequest))\
- .AndReturn([tenants, False])
-
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
-
- self.assertTemplateUsed(res, 'admin/networks/index.html')
- networks = res.context['networks_table'].data
- self.assertItemsEqual(networks, self.networks.list())
-
- @test.create_stubs({api.neutron: ('network_list',)})
- def test_index_network_list_exception(self):
- api.neutron.network_list(IsA(http.HttpRequest)) \
- .AndRaise(self.exceptions.neutron)
-
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
-
- self.assertTemplateUsed(res, 'admin/networks/index.html')
- self.assertEqual(len(res.context['networks_table'].data), 0)
- self.assertMessageCount(res, error=1)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_list',
- 'port_list',)})
- def test_network_detail(self):
- network_id = self.networks.first().id
- api.neutron.network_get(IsA(http.HttpRequest), network_id)\
- .AndReturn(self.networks.first())
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.subnets.first()])
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.ports.first()])
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:networks:detail',
- args=[network_id]))
-
- self.assertTemplateUsed(res, 'project/networks/detail.html')
- subnets = res.context['subnets_table'].data
- ports = res.context['ports_table'].data
- self.assertItemsEqual(subnets, [self.subnets.first()])
- self.assertItemsEqual(ports, [self.ports.first()])
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_list',
- 'port_list',)})
- def test_network_detail_network_exception(self):
- network_id = self.networks.first().id
- api.neutron.network_get(IsA(http.HttpRequest), network_id)\
- .AndRaise(self.exceptions.neutron)
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.subnets.first()])
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.ports.first()])
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:networks:detail', args=[network_id])
- res = self.client.get(url)
-
- redir_url = INDEX_URL
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_list',
- 'port_list',)})
- def test_network_detail_subnet_exception(self):
- network_id = self.networks.first().id
- api.neutron.network_get(IsA(http.HttpRequest), network_id).\
- AndReturn(self.networks.first())
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id).\
- AndRaise(self.exceptions.neutron)
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id).\
- AndReturn([self.ports.first()])
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:networks:detail',
- args=[network_id]))
-
- self.assertTemplateUsed(res, 'project/networks/detail.html')
- subnets = res.context['subnets_table'].data
- ports = res.context['ports_table'].data
- self.assertEqual(len(subnets), 0)
- self.assertItemsEqual(ports, [self.ports.first()])
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_list',
- 'port_list',)})
- def test_network_detail_port_exception(self):
- network_id = self.networks.first().id
- api.neutron.network_get(IsA(http.HttpRequest), network_id).\
- AndReturn(self.networks.first())
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id).\
- AndReturn([self.subnets.first()])
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id).\
- AndRaise(self.exceptions.neutron)
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:networks:detail',
- args=[network_id]))
-
- self.assertTemplateUsed(res, 'project/networks/detail.html')
- subnets = res.context['subnets_table'].data
- ports = res.context['ports_table'].data
- self.assertItemsEqual(subnets, [self.subnets.first()])
- self.assertEqual(len(ports), 0)
-
- @test.create_stubs({api.keystone: ('tenant_list',)})
- def test_network_create_get(self):
- tenants = self.tenants.list()
- api.keystone.tenant_list(IsA(http.HttpRequest))\
- .AndReturn([tenants, False])
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:networks:create')
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, 'admin/networks/create.html')
-
- @test.create_stubs({api.neutron: ('network_create',),
- api.keystone: ('tenant_list',)})
- def test_network_create_post(self):
- tenants = self.tenants.list()
- tenant_id = self.tenants.first().id
- network = self.networks.first()
- api.keystone.tenant_list(IsA(http.HttpRequest))\
- .AndReturn([tenants, False])
- params = {'name': network.name,
- 'tenant_id': tenant_id,
- 'admin_state_up': network.admin_state_up,
- 'router:external': True,
- 'shared': True}
- api.neutron.network_create(IsA(http.HttpRequest), **params)\
- .AndReturn(network)
- self.mox.ReplayAll()
-
- form_data = {'tenant_id': tenant_id,
- 'name': network.name,
- 'admin_state': network.admin_state_up,
- 'external': True,
- 'shared': True}
- url = reverse('horizon:admin:networks:create')
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_create',),
- api.keystone: ('tenant_list',)})
- def test_network_create_post_network_exception(self):
- tenants = self.tenants.list()
- tenant_id = self.tenants.first().id
- network = self.networks.first()
- api.keystone.tenant_list(IsA(http.HttpRequest))\
- .AndReturn([tenants, False])
- params = {'name': network.name,
- 'tenant_id': tenant_id,
- 'admin_state_up': network.admin_state_up,
- 'router:external': True,
- 'shared': False}
- api.neutron.network_create(IsA(http.HttpRequest), **params)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- form_data = {'tenant_id': tenant_id,
- 'name': network.name,
- 'admin_state': network.admin_state_up,
- 'external': True,
- 'shared': False}
- url = reverse('horizon:admin:networks:create')
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_network_update_get(self):
- network = self.networks.first()
- api.neutron.network_get(IsA(http.HttpRequest), network.id)\
- .AndReturn(network)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:networks:update', args=[network.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, 'admin/networks/update.html')
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_network_update_get_exception(self):
- network = self.networks.first()
- api.neutron.network_get(IsA(http.HttpRequest), network.id)\
- .AndRaise(self.exceptions.neutron)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:networks:update', args=[network.id])
- res = self.client.get(url)
-
- redir_url = INDEX_URL
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_modify',
- 'network_get',)})
- def test_network_update_post(self):
- network = self.networks.first()
- params = {'name': network.name,
- 'shared': True,
- 'admin_state_up': network.admin_state_up,
- 'router:external': True}
- api.neutron.network_modify(IsA(http.HttpRequest), network.id,
- **params)\
- .AndReturn(network)
- api.neutron.network_get(IsA(http.HttpRequest), network.id)\
- .AndReturn(network)
- self.mox.ReplayAll()
-
- form_data = {'network_id': network.id,
- 'name': network.name,
- 'tenant_id': network.tenant_id,
- 'admin_state': network.admin_state_up,
- 'shared': True,
- 'external': True}
- url = reverse('horizon:admin:networks:update', args=[network.id])
- res = self.client.post(url, form_data)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_modify',
- 'network_get',)})
- def test_network_update_post_exception(self):
- network = self.networks.first()
- params = {'name': network.name,
- 'shared': False,
- 'admin_state_up': network.admin_state_up,
- 'router:external': False}
- api.neutron.network_modify(IsA(http.HttpRequest), network.id,
- **params)\
- .AndRaise(self.exceptions.neutron)
- api.neutron.network_get(IsA(http.HttpRequest), network.id)\
- .AndReturn(network)
- self.mox.ReplayAll()
-
- form_data = {'network_id': network.id,
- 'name': network.name,
- 'tenant_id': network.tenant_id,
- 'admin_state': network.admin_state_up,
- 'shared': False,
- 'external': False}
- url = reverse('horizon:admin:networks:update', args=[network.id])
- res = self.client.post(url, form_data)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_list',
- 'network_delete'),
- api.keystone: ('tenant_list',)})
- def test_delete_network(self):
- tenants = self.tenants.list()
- network = self.networks.first()
- api.keystone.tenant_list(IsA(http.HttpRequest))\
- .AndReturn([tenants, False])
- api.neutron.network_list(IsA(http.HttpRequest))\
- .AndReturn([network])
- api.neutron.network_delete(IsA(http.HttpRequest), network.id)
-
- self.mox.ReplayAll()
-
- form_data = {'action': 'networks__delete__%s' % network.id}
- res = self.client.post(INDEX_URL, form_data)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_list',
- 'network_delete'),
- api.keystone: ('tenant_list',)})
- def test_delete_network_exception(self):
- tenants = self.tenants.list()
- network = self.networks.first()
- api.keystone.tenant_list(IsA(http.HttpRequest))\
- .AndReturn([tenants, False])
- api.neutron.network_list(IsA(http.HttpRequest))\
- .AndReturn([network])
- api.neutron.network_delete(IsA(http.HttpRequest), network.id)\
- .AndRaise(self.exceptions.neutron)
-
- self.mox.ReplayAll()
-
- form_data = {'action': 'networks__delete__%s' % network.id}
- res = self.client.post(INDEX_URL, form_data)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
-
-class NetworkSubnetTests(test.BaseAdminViewTests):
-
- @test.create_stubs({api.neutron: ('subnet_get',)})
- def test_subnet_detail(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(self.subnets.first())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:networks:subnets:detail',
- args=[subnet.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, 'project/networks/subnets/detail.html')
- self.assertEqual(res.context['subnet'].id, subnet.id)
-
- @test.create_stubs({api.neutron: ('subnet_get',)})
- def test_subnet_detail_exception(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndRaise(self.exceptions.neutron)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:networks:subnets:detail',
- args=[subnet.id])
- res = self.client.get(url)
-
- # admin DetailView is shared with userpanel one, so
- # redirection URL on error is userpanel index.
- redir_url = reverse('horizon:project:networks:index')
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_get(self):
- network = self.networks.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:networks:addsubnet',
- args=[network.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_create',)})
- def test_subnet_create_post(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.subnet_create(IsA(http.HttpRequest),
- network_id=network.id,
- name=subnet.name,
- cidr=subnet.cidr,
- ip_version=subnet.ip_version,
- gateway_ip=subnet.gateway_ip,
- enable_dhcp=subnet.enable_dhcp,
- allocation_pools=subnet.allocation_pools,
- tenant_id=subnet.tenant_id)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet)
- url = reverse('horizon:admin:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- redir_url = reverse('horizon:admin:networks:detail',
- args=[subnet.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_create',)})
- def test_subnet_create_post_network_exception(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet, allocation_pools=[])
- url = reverse('horizon:admin:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- # admin DetailView is shared with userpanel one, so
- # redirection URL on error is userpanel index.
- redir_url = reverse('horizon:project:networks:index')
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_create',)})
- def test_subnet_create_post_subnet_exception(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.subnet_create(IsA(http.HttpRequest),
- network_id=network.id,
- name=subnet.name,
- cidr=subnet.cidr,
- ip_version=subnet.ip_version,
- gateway_ip=subnet.gateway_ip,
- enable_dhcp=subnet.enable_dhcp,
- tenant_id=subnet.tenant_id)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet, allocation_pools=[])
- url = reverse('horizon:admin:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- redir_url = reverse('horizon:admin:networks:detail',
- args=[subnet.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_cidr_inconsistent(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- self.mox.ReplayAll()
-
- # dummy IPv6 address
- cidr = '2001:0DB8:0:CD30:123:4567:89AB:CDEF/60'
- form_data = form_data_subnet(subnet, cidr=cidr, allocation_pools=[])
- url = reverse('horizon:admin:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- expected_msg = 'Network Address and IP version are inconsistent.'
- self.assertContains(res, expected_msg)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_gw_inconsistent(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- self.mox.ReplayAll()
-
- # dummy IPv6 address
- gateway_ip = '2001:0DB8:0:CD30:123:4567:89AB:CDEF'
- form_data = form_data_subnet(subnet, gateway_ip=gateway_ip,
- allocation_pools=[])
- url = reverse('horizon:admin:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res, 'Gateway IP and IP version are inconsistent.')
-
- @test.create_stubs({api.neutron: ('subnet_modify',
- 'subnet_get',)})
- def test_subnet_update_post(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(subnet)
- api.neutron.subnet_modify(IsA(http.HttpRequest), subnet.id,
- name=subnet.name,
- gateway_ip=subnet.gateway_ip,
- enable_dhcp=subnet.enable_dhcp,
- dns_nameservers=[],
- host_routes=[])\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet, allocation_pools=[])
- url = reverse('horizon:admin:networks:editsubnet',
- args=[subnet.network_id, subnet.id])
- res = self.client.post(url, form_data)
-
- redir_url = reverse('horizon:admin:networks:detail',
- args=[subnet.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('subnet_modify',
- 'subnet_get',)})
- def test_subnet_update_post_gw_inconsistent(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- # dummy IPv6 address
- gateway_ip = '2001:0DB8:0:CD30:123:4567:89AB:CDEF'
- form_data = form_data_subnet(subnet, gateway_ip=gateway_ip,
- allocation_pools=[])
- url = reverse('horizon:admin:networks:editsubnet',
- args=[subnet.network_id, subnet.id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res, 'Gateway IP and IP version are inconsistent.')
-
- @test.create_stubs({api.neutron: ('subnet_delete',
- 'subnet_list',
- 'port_list',)})
- def test_subnet_delete(self):
- subnet = self.subnets.first()
- network_id = subnet.network_id
- api.neutron.subnet_delete(IsA(http.HttpRequest), subnet.id)
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.subnets.first()])
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.ports.first()])
- self.mox.ReplayAll()
-
- form_data = {'action': 'subnets__delete__%s' % subnet.id}
- url = reverse('horizon:admin:networks:detail',
- args=[network_id])
- res = self.client.post(url, form_data)
-
- self.assertRedirectsNoFollow(res, url)
-
- @test.create_stubs({api.neutron: ('subnet_delete',
- 'subnet_list',
- 'port_list',)})
- def test_subnet_delete_exception(self):
- subnet = self.subnets.first()
- network_id = subnet.network_id
- api.neutron.subnet_delete(IsA(http.HttpRequest), subnet.id)\
- .AndRaise(self.exceptions.neutron)
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.subnets.first()])
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.ports.first()])
- self.mox.ReplayAll()
-
- form_data = {'action': 'subnets__delete__%s' % subnet.id}
- url = reverse('horizon:admin:networks:detail',
- args=[network_id])
- res = self.client.post(url, form_data)
-
- self.assertRedirectsNoFollow(res, url)
-
-
-class NetworkPortTests(test.BaseAdminViewTests):
-
- @test.create_stubs({api.neutron: ('port_get',)})
- def test_port_detail(self):
- port = self.ports.first()
- api.neutron.port_get(IsA(http.HttpRequest), port.id)\
- .AndReturn(self.ports.first())
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:networks:ports:detail',
- args=[port.id]))
-
- self.assertTemplateUsed(res, 'project/networks/ports/detail.html')
- self.assertEqual(res.context['port'].id, port.id)
-
- @test.create_stubs({api.neutron: ('port_get',)})
- def test_port_detail_exception(self):
- port = self.ports.first()
- api.neutron.port_get(IsA(http.HttpRequest), port.id)\
- .AndRaise(self.exceptions.neutron)
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:networks:ports:detail',
- args=[port.id]))
-
- # admin DetailView is shared with userpanel one, so
- # redirection URL on error is userpanel index.
- redir_url = reverse('horizon:project:networks:index')
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_port_create_get(self):
- network = self.networks.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:networks:addport',
- args=[network.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, 'admin/networks/ports/create.html')
-
- @test.create_stubs({api.neutron: ('network_get',
- 'port_create')})
- def test_port_create_post(self):
- network = self.networks.first()
- port = self.ports.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.port_create(IsA(http.HttpRequest),
- tenant_id=network.tenant_id,
- network_id=network.id,
- name=port.name,
- admin_state_up=port.admin_state_up,
- device_id=port.device_id,
- device_owner=port.device_owner)\
- .AndReturn(port)
- self.mox.ReplayAll()
-
- form_data = {'network_id': port.network_id,
- 'network_name': network.name,
- 'name': port.name,
- 'admin_state': port.admin_state_up,
- 'device_id': port.device_id,
- 'device_owner': port.device_owner}
- url = reverse('horizon:admin:networks:addport',
- args=[port.network_id])
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- redir_url = reverse('horizon:admin:networks:detail',
- args=[port.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'port_create')})
- def test_port_create_post_exception(self):
- network = self.networks.first()
- port = self.ports.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.port_create(IsA(http.HttpRequest),
- tenant_id=network.tenant_id,
- network_id=network.id,
- name=port.name,
- admin_state_up=port.admin_state_up,
- device_id=port.device_id,
- device_owner=port.device_owner)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- form_data = {'network_id': port.network_id,
- 'network_name': network.name,
- 'name': port.name,
- 'admin_state': port.admin_state_up,
- 'device_id': port.device_id,
- 'device_owner': port.device_owner}
- url = reverse('horizon:admin:networks:addport',
- args=[port.network_id])
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- redir_url = reverse('horizon:admin:networks:detail',
- args=[port.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('port_get',)})
- def test_port_update_get(self):
- port = self.ports.first()
- api.neutron.port_get(IsA(http.HttpRequest),
- port.id)\
- .AndReturn(port)
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:networks:editport',
- args=[port.network_id, port.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, 'admin/networks/ports/update.html')
-
- @test.create_stubs({api.neutron: ('port_get',
- 'port_modify')})
- def test_port_update_post(self):
- port = self.ports.first()
- api.neutron.port_get(IsA(http.HttpRequest), port.id)\
- .AndReturn(port)
- api.neutron.port_modify(IsA(http.HttpRequest), port.id,
- name=port.name,
- admin_state_up=port.admin_state_up,
- device_id=port.device_id,
- device_owner=port.device_owner)\
- .AndReturn(port)
- self.mox.ReplayAll()
-
- form_data = {'network_id': port.network_id,
- 'port_id': port.id,
- 'name': port.name,
- 'admin_state': port.admin_state_up,
- 'device_id': port.device_id,
- 'device_owner': port.device_owner}
- url = reverse('horizon:admin:networks:editport',
- args=[port.network_id, port.id])
- res = self.client.post(url, form_data)
-
- redir_url = reverse('horizon:admin:networks:detail',
- args=[port.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('port_get',
- 'port_modify')})
- def test_port_update_post_exception(self):
- port = self.ports.first()
- api.neutron.port_get(IsA(http.HttpRequest), port.id)\
- .AndReturn(port)
- api.neutron.port_modify(IsA(http.HttpRequest), port.id,
- name=port.name,
- admin_state_up=port.admin_state_up,
- device_id=port.device_id,
- device_owner=port.device_owner)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- form_data = {'network_id': port.network_id,
- 'port_id': port.id,
- 'name': port.name,
- 'admin_state': port.admin_state_up,
- 'device_id': port.device_id,
- 'device_owner': port.device_owner}
- url = reverse('horizon:admin:networks:editport',
- args=[port.network_id, port.id])
- res = self.client.post(url, form_data)
-
- redir_url = reverse('horizon:admin:networks:detail',
- args=[port.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('port_delete',
- 'subnet_list',
- 'port_list',)})
- def test_port_delete(self):
- port = self.ports.first()
- network_id = port.network_id
- api.neutron.port_delete(IsA(http.HttpRequest), port.id)
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.subnets.first()])
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.ports.first()])
- self.mox.ReplayAll()
-
- form_data = {'action': 'ports__delete__%s' % port.id}
- url = reverse('horizon:admin:networks:detail',
- args=[network_id])
- res = self.client.post(url, form_data)
-
- self.assertRedirectsNoFollow(res, url)
-
- @test.create_stubs({api.neutron: ('port_delete',
- 'subnet_list',
- 'port_list',)})
- def test_port_delete_exception(self):
- port = self.ports.first()
- network_id = port.network_id
- api.neutron.port_delete(IsA(http.HttpRequest), port.id)\
- .AndRaise(self.exceptions.neutron)
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.subnets.first()])
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.ports.first()])
- self.mox.ReplayAll()
-
- form_data = {'action': 'ports__delete__%s' % port.id}
- url = reverse('horizon:admin:networks:detail',
- args=[network_id])
- res = self.client.post(url, form_data)
-
- self.assertRedirectsNoFollow(res, url)
diff --git a/openstack_dashboard/dashboards/admin/networks/urls.py b/openstack_dashboard/dashboards/admin/networks/urls.py
deleted file mode 100644
index ddf87880..00000000
--- a/openstack_dashboard/dashboards/admin/networks/urls.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.defaults import include
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.networks.views import CreateView
-from openstack_dashboard.dashboards.admin.networks.views import DetailView
-from openstack_dashboard.dashboards.admin.networks.views import IndexView
-from openstack_dashboard.dashboards.admin.networks.views import UpdateView
-
-from openstack_dashboard.dashboards.admin.networks.subnets \
- import urls as subnet_urls
-from openstack_dashboard.dashboards.admin.networks.subnets.views \
- import CreateView as AddSubnetView
-from openstack_dashboard.dashboards.admin.networks.subnets.views \
- import UpdateView as EditSubnetView
-
-from openstack_dashboard.dashboards.admin.networks.ports \
- import urls as port_urls
-from openstack_dashboard.dashboards.admin.networks.ports.views \
- import CreateView as AddPortView
-from openstack_dashboard.dashboards.admin.networks.ports.views \
- import UpdateView as EditPortView
-
-
-NETWORKS = r'^(?P<network_id>[^/]+)/%s$'
-
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^create/$', CreateView.as_view(), name='create'),
- url(NETWORKS % 'update', UpdateView.as_view(), name='update'),
- # for detail view
- url(NETWORKS % 'detail', DetailView.as_view(), name='detail'),
- url(NETWORKS % 'subnets/create', AddSubnetView.as_view(),
- name='addsubnet'),
- url(NETWORKS % 'ports/create', AddPortView.as_view(), name='addport'),
- url(r'^(?P<network_id>[^/]+)/subnets/(?P<subnet_id>[^/]+)/update$',
- EditSubnetView.as_view(), name='editsubnet'),
- url(r'^(?P<network_id>[^/]+)/ports/(?P<port_id>[^/]+)/update$',
- EditPortView.as_view(), name='editport'),
-
- url(r'^subnets/', include(subnet_urls, namespace='subnets')),
- url(r'^ports/', include(port_urls, namespace='ports')))
diff --git a/openstack_dashboard/dashboards/admin/networks/views.py b/openstack_dashboard/dashboards/admin/networks/views.py
deleted file mode 100644
index 0cee09fa..00000000
--- a/openstack_dashboard/dashboards/admin/networks/views.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse_lazy
-from django.utils.datastructures import SortedDict
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.networks import views as user_views
-
-from openstack_dashboard.dashboards.admin.networks.forms import CreateNetwork
-from openstack_dashboard.dashboards.admin.networks.forms import UpdateNetwork
-from openstack_dashboard.dashboards.admin.networks.ports.tables \
- import PortsTable
-from openstack_dashboard.dashboards.admin.networks.subnets.tables \
- import SubnetsTable
-from openstack_dashboard.dashboards.admin.networks.tables import NetworksTable
-
-
-LOG = logging.getLogger(__name__)
-
-
-class IndexView(tables.DataTableView):
- table_class = NetworksTable
- template_name = 'admin/networks/index.html'
-
- def _get_tenant_list(self):
- if not hasattr(self, "_tenants"):
- try:
- tenants, has_more = api.keystone.tenant_list(self.request)
- except:
- tenants = []
- msg = _('Unable to retrieve instance project information.')
- exceptions.handle(self.request, msg)
-
- tenant_dict = SortedDict([(t.id, t) for t in tenants])
- self._tenants = tenant_dict
- return self._tenants
-
- def get_data(self):
- try:
- networks = api.neutron.network_list(self.request)
- except:
- networks = []
- msg = _('Network list can not be retrieved.')
- exceptions.handle(self.request, msg)
- if networks:
- tenant_dict = self._get_tenant_list()
- for n in networks:
- # Set tenant name
- tenant = tenant_dict.get(n.tenant_id, None)
- n.tenant_name = getattr(tenant, 'name', None)
- # If name is empty use UUID as name
- n.set_id_as_name_if_empty()
- return networks
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateNetwork
- template_name = 'admin/networks/create.html'
- success_url = reverse_lazy('horizon:admin:networks:index')
-
-
-class DetailView(tables.MultiTableView):
- table_classes = (SubnetsTable, PortsTable)
- template_name = 'project/networks/detail.html'
- failure_url = reverse_lazy('horizon:admin:networks:index')
-
- def get_subnets_data(self):
- try:
- network_id = self.kwargs['network_id']
- subnets = api.neutron.subnet_list(self.request,
- network_id=network_id)
- except:
- subnets = []
- msg = _('Subnet list can not be retrieved.')
- exceptions.handle(self.request, msg)
- for s in subnets:
- s.set_id_as_name_if_empty()
- return subnets
-
- def get_ports_data(self):
- try:
- network_id = self.kwargs['network_id']
- ports = api.neutron.port_list(self.request, network_id=network_id)
- except:
- ports = []
- msg = _('Port list can not be retrieved.')
- exceptions.handle(self.request, msg)
- for p in ports:
- p.set_id_as_name_if_empty()
- return ports
-
- def _get_data(self):
- if not hasattr(self, "_network"):
- try:
- network_id = self.kwargs['network_id']
- network = api.neutron.network_get(self.request, network_id)
- network.set_id_as_name_if_empty(length=0)
- except:
- redirect = self.failure_url
- exceptions.handle(self.request,
- _('Unable to retrieve details for '
- 'network "%s".') % network_id,
- redirect=redirect)
- self._network = network
- return self._network
-
- def get_context_data(self, **kwargs):
- context = super(DetailView, self).get_context_data(**kwargs)
- context["network"] = self._get_data()
- return context
-
-
-class UpdateView(user_views.UpdateView):
- form_class = UpdateNetwork
- template_name = 'admin/networks/update.html'
- success_url = reverse_lazy('horizon:admin:networks:index')
-
- def get_initial(self):
- network = self._get_object()
- return {'network_id': network['id'],
- 'tenant_id': network['tenant_id'],
- 'name': network['name'],
- 'admin_state': network['admin_state_up'],
- 'shared': network['shared'],
- 'external': network['router__external']}
diff --git a/openstack_dashboard/dashboards/admin/overview/__init__.py b/openstack_dashboard/dashboards/admin/overview/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/overview/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/overview/panel.py b/openstack_dashboard/dashboards/admin/overview/panel.py
deleted file mode 100644
index ec237578..00000000
--- a/openstack_dashboard/dashboards/admin/overview/panel.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Overview(horizon.Panel):
- name = _("Overview")
- slug = 'overview'
- permissions = ('openstack.roles.admin',)
-
-
-dashboard.Admin.register(Overview)
diff --git a/openstack_dashboard/dashboards/admin/overview/templates/overview/usage.csv b/openstack_dashboard/dashboards/admin/overview/templates/overview/usage.csv
deleted file mode 100644
index 3749ee2a..00000000
--- a/openstack_dashboard/dashboards/admin/overview/templates/overview/usage.csv
+++ /dev/null
@@ -1,6 +0,0 @@
-{% load i18n %}{% trans "Usage Report For Period" %}:,{{ usage.start|date:"b. d Y" }},{{ usage.end|date:"b. d Y" }}
-{% trans "Active Instances" %}:,{{ usage.summary.instances }}
-{% trans "CPU-HRs Used" %}:,{{ usage.summary.vcpu_hours|floatformat:2 }}
-{% trans "Total Active RAM (MB)" %}:,{{ usage.summary.memory_mb }}
-{% trans "Total Disk Size" %}:,{{ usage.summary.local_gb }}
-{% trans "Total Disk Usage" %}:,{{ usage.summary.disk_gb_hours|floatformat:2 }}
diff --git a/openstack_dashboard/dashboards/admin/overview/templates/overview/usage.html b/openstack_dashboard/dashboards/admin/overview/templates/overview/usage.html
deleted file mode 100644
index 7f53c2a9..00000000
--- a/openstack_dashboard/dashboards/admin/overview/templates/overview/usage.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n sizeformat %}
-{% block title %}{% trans "Usage Overview" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Overview") %}
-{% endblock page_header %}
-
-{% block main %}
- {% if monitoring %}
- <div id="monitoring">
- <h3>{% trans "Monitoring" %}: </h3>
- <ul id="external_links">
- {% for link in monitoring %}
- <li><a target="_blank" href="{{ link.1 }}">{{ link.0 }}</a></li>
- {% endfor %}
- </ul>
- </div>
- {% endif %}
- {% include "horizon/common/_usage_summary.html" %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/overview/tests.py b/openstack_dashboard/dashboards/admin/overview/tests.py
deleted file mode 100644
index 22499285..00000000
--- a/openstack_dashboard/dashboards/admin/overview/tests.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import datetime
-
-from django.core.urlresolvers import reverse
-from django import http
-from django.utils import timezone
-
-from mox import IsA
-
-from horizon.templatetags.sizeformat import mbformat
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-from openstack_dashboard import usage
-
-
-INDEX_URL = reverse('horizon:project:overview:index')
-
-
-class UsageViewTests(test.BaseAdminViewTests):
-
- @test.create_stubs({api.nova: ('usage_list', 'tenant_absolute_limits', ),
- api.keystone: ('tenant_list',)})
- def test_usage(self):
- now = timezone.now()
- usage_obj = api.nova.NovaUsage(self.usages.first())
- api.keystone.tenant_list(IsA(http.HttpRequest)) \
- .AndReturn([self.tenants.list(), False])
- api.nova.usage_list(IsA(http.HttpRequest),
- datetime.datetime(now.year,
- now.month,
- now.day, 0, 0, 0, 0),
- datetime.datetime(now.year,
- now.month,
- now.day, 23, 59, 59, 0)) \
- .AndReturn([usage_obj])
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest)) \
- .AndReturn(self.limits['absolute'])
- self.mox.ReplayAll()
- res = self.client.get(reverse('horizon:admin:overview:index'))
- self.assertTemplateUsed(res, 'admin/overview/usage.html')
- self.assertTrue(isinstance(res.context['usage'], usage.GlobalUsage))
- self.assertContains(res,
- '<td class="sortable normal_column">test_tenant'
- '</td>'
- '<td class="sortable normal_column">%s</td>'
- '<td class="sortable normal_column">%s</td>'
- '<td class="sortable normal_column">%s</td>'
- '<td class="sortable normal_column">%.2f</td>'
- '<td class="sortable normal_column">%.2f</td>' %
- (usage_obj.vcpus,
- usage_obj.disk_gb_hours,
- mbformat(usage_obj.memory_mb),
- usage_obj.vcpu_hours,
- usage_obj.total_local_gb_usage))
-
- @test.create_stubs({api.nova: ('usage_list', 'tenant_absolute_limits', ),
- api.keystone: ('tenant_list',)})
- def test_usage_csv(self):
- now = timezone.now()
- usage_obj = [api.nova.NovaUsage(u) for u in self.usages.list()]
- api.keystone.tenant_list(IsA(http.HttpRequest)) \
- .AndReturn([self.tenants.list(), False])
- api.nova.usage_list(IsA(http.HttpRequest),
- datetime.datetime(now.year,
- now.month,
- now.day, 0, 0, 0, 0),
- datetime.datetime(now.year,
- now.month,
- now.day, 23, 59, 59, 0)) \
- .AndReturn(usage_obj)
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\
- .AndReturn(self.limits['absolute'])
- self.mox.ReplayAll()
- csv_url = reverse('horizon:admin:overview:index') + "?format=csv"
- res = self.client.get(csv_url)
- self.assertTemplateUsed(res, 'admin/overview/usage.csv')
- self.assertTrue(isinstance(res.context['usage'], usage.GlobalUsage))
- hdr = 'Project Name,VCPUs,Ram (MB),Disk (GB),Usage (Hours)'
- self.assertContains(res, '%s\r\n' % (hdr))
- for obj in usage_obj:
- row = u'{0},{1},{2},{3},{4:.2f}\r\n'.format(obj.project_name,
- obj.vcpus,
- obj.memory_mb,
- obj.disk_gb_hours,
- obj.vcpu_hours)
- self.assertContains(res, row)
diff --git a/openstack_dashboard/dashboards/admin/overview/urls.py b/openstack_dashboard/dashboards/admin/overview/urls.py
deleted file mode 100644
index 6cf1bde0..00000000
--- a/openstack_dashboard/dashboards/admin/overview/urls.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.overview.views import GlobalOverview
-
-
-urlpatterns = patterns('',
- url(r'^$', GlobalOverview.as_view(), name='index'),
-)
diff --git a/openstack_dashboard/dashboards/admin/overview/views.py b/openstack_dashboard/dashboards/admin/overview/views.py
deleted file mode 100644
index 600ab2f1..00000000
--- a/openstack_dashboard/dashboards/admin/overview/views.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf import settings
-from django.template.defaultfilters import floatformat
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-
-from openstack_dashboard import api
-from openstack_dashboard import usage
-from openstack_dashboard.usage.base import BaseCsvResponse
-
-
-class GlobalUsageCsvRenderer(BaseCsvResponse):
-
- columns = [_("Project Name"), _("VCPUs"), _("Ram (MB)"),
- _("Disk (GB)"), _("Usage (Hours)")]
-
- def get_row_data(self):
-
- for u in self.context['usage'].usage_list:
- yield (u.project_name or u.tenant_id,
- u.vcpus,
- u.memory_mb,
- u.local_gb,
- floatformat(u.vcpu_hours, 2))
-
-
-class GlobalOverview(usage.UsageView):
- table_class = usage.GlobalUsageTable
- usage_class = usage.GlobalUsage
- template_name = 'admin/overview/usage.html'
- csv_response_class = GlobalUsageCsvRenderer
-
- def get_context_data(self, **kwargs):
- context = super(GlobalOverview, self).get_context_data(**kwargs)
- context['monitoring'] = getattr(settings, 'EXTERNAL_MONITORING', [])
- return context
-
- def get_data(self):
- data = super(GlobalOverview, self).get_data()
- # Pre-fill project names
- try:
- projects, has_more = api.keystone.tenant_list(self.request)
- except:
- projects = []
- exceptions.handle(self.request,
- _('Unable to retrieve project list.'))
- for instance in data:
- project = filter(lambda t: t.id == instance.tenant_id, projects)
- if project:
- instance.project_name = getattr(project[0], "name", None)
- else:
- instance.project_name = None
- return data
diff --git a/openstack_dashboard/dashboards/admin/projects/__init__.py b/openstack_dashboard/dashboards/admin/projects/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/projects/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/projects/forms.py b/openstack_dashboard/dashboards/admin/projects/forms.py
deleted file mode 100644
index 563ae503..00000000
--- a/openstack_dashboard/dashboards/admin/projects/forms.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from horizon import forms
-
-from openstack_dashboard.dashboards.admin.users.forms import CreateUserForm
-
-
-class CreateUser(CreateUserForm):
- role_id = forms.ChoiceField(widget=forms.HiddenInput())
- project = forms.CharField(widget=forms.HiddenInput())
-
- def __init__(self, request, *args, **kwargs):
- super(CreateUser, self).__init__(request, *args, **kwargs)
- project = self.request.path.split("/")[-1]
- self.fields['project'].initial = project
diff --git a/openstack_dashboard/dashboards/admin/projects/panel.py b/openstack_dashboard/dashboards/admin/projects/panel.py
deleted file mode 100644
index 8eb9757d..00000000
--- a/openstack_dashboard/dashboards/admin/projects/panel.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Tenants(horizon.Panel):
- name = _("Projects")
- slug = 'projects'
-
-
-dashboard.Admin.register(Tenants)
diff --git a/openstack_dashboard/dashboards/admin/projects/tables.py b/openstack_dashboard/dashboards/admin/projects/tables.py
deleted file mode 100644
index b6f76e71..00000000
--- a/openstack_dashboard/dashboards/admin/projects/tables.py
+++ /dev/null
@@ -1,168 +0,0 @@
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.http import urlencode
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.admin.users.tables import UsersTable
-
-
-LOG = logging.getLogger(__name__)
-
-
-class ViewMembersLink(tables.LinkAction):
- name = "users"
- verbose_name = _("Modify Users")
- url = "horizon:admin:projects:update"
- classes = ("ajax-modal", "btn-edit")
-
- def get_link_url(self, project):
- step = 'update_members'
- base_url = reverse(self.url, args=[project.id])
- param = urlencode({"step": step})
- return "?".join([base_url, param])
-
-
-class UsageLink(tables.LinkAction):
- name = "usage"
- verbose_name = _("View Usage")
- url = "horizon:admin:projects:usage"
- classes = ("btn-stats",)
-
-
-class CreateProject(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Project")
- url = "horizon:admin:projects:create"
- classes = ("btn-launch", "ajax-modal",)
-
- def allowed(self, request, project):
- return api.keystone.keystone_can_edit_project()
-
-
-class UpdateProject(tables.LinkAction):
- name = "update"
- verbose_name = _("Edit Project")
- url = "horizon:admin:projects:update"
- classes = ("ajax-modal", "btn-edit")
-
- def allowed(self, request, project):
- return api.keystone.keystone_can_edit_project()
-
-
-class ModifyQuotas(tables.LinkAction):
- name = "quotas"
- verbose_name = "Modify Quotas"
- url = "horizon:admin:projects:update"
- classes = ("ajax-modal", "btn-edit")
-
- def get_link_url(self, project):
- step = 'update_quotas'
- base_url = reverse(self.url, args=[project.id])
- param = urlencode({"step": step})
- return "?".join([base_url, param])
-
-
-class DeleteTenantsAction(tables.DeleteAction):
- data_type_singular = _("Project")
- data_type_plural = _("Projects")
-
- def allowed(self, request, project):
- return api.keystone.keystone_can_edit_project()
-
- def delete(self, request, obj_id):
- api.keystone.tenant_delete(request, obj_id)
-
-
-class TenantFilterAction(tables.FilterAction):
- def filter(self, table, tenants, filter_string):
- """ Really naive case-insensitive search. """
- # FIXME(gabriel): This should be smarter. Written for demo purposes.
- q = filter_string.lower()
-
- def comp(tenant):
- if q in tenant.name.lower():
- return True
- return False
-
- return filter(comp, tenants)
-
-
-class TenantsTable(tables.DataTable):
- name = tables.Column('name', verbose_name=_('Name'))
- description = tables.Column(lambda obj: getattr(obj, 'description', None),
- verbose_name=_('Description'))
- id = tables.Column('id', verbose_name=_('Project ID'))
- enabled = tables.Column('enabled', verbose_name=_('Enabled'), status=True)
-
- class Meta:
- name = "tenants"
- verbose_name = _("Projects")
- row_actions = (ViewMembersLink, UpdateProject, UsageLink,
- ModifyQuotas, DeleteTenantsAction)
- table_actions = (TenantFilterAction, CreateProject,
- DeleteTenantsAction)
- pagination_param = "tenant_marker"
-
-
-class RemoveUserAction(tables.BatchAction):
- name = "remove_user"
- action_present = _("Remove")
- action_past = _("Removed")
- data_type_singular = _("User")
- data_type_plural = _("Users")
- classes = ('btn-danger',)
-
- def action(self, request, user_id):
- tenant_id = self.table.kwargs['tenant_id']
- api.keystone.remove_tenant_user(request, tenant_id, user_id)
-
-
-class ProjectUserRolesColumn(tables.Column):
- def get_raw_data(self, user):
- request = self.table.request
- try:
- roles = api.keystone.roles_for_user(request,
- user.id,
- self.table.kwargs["tenant_id"])
- except:
- roles = []
- exceptions.handle(request,
- _("Unable to retrieve role information."))
- return ", ".join([role.name for role in roles])
-
-
-class TenantUsersTable(UsersTable):
- roles = ProjectUserRolesColumn("roles", verbose_name=_("Roles"))
-
- class Meta:
- name = "tenant_users"
- verbose_name = _("Users For Project")
- table_actions = (RemoveUserAction,)
- row_actions = (RemoveUserAction,)
- columns = ("name", "email", "id", "roles", "enabled")
-
-
-class AddUserAction(tables.LinkAction):
- name = "add_user"
- verbose_name = _("Add To Project")
- url = "horizon:admin:projects:add_user"
- classes = ('ajax-modal',)
-
- def get_link_url(self, user):
- tenant_id = self.table.kwargs['tenant_id']
- return reverse(self.url, args=(tenant_id, user.id))
-
-
-class AddUsersTable(UsersTable):
- class Meta:
- name = "add_users"
- verbose_name = _("Add New Users")
- table_actions = ()
- row_actions = (AddUserAction,)
- columns = ("name", "email", "id", "enabled")
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/_add_user.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/_add_user.html
deleted file mode 100644
index 046c951e..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/_add_user.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}add_user_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:projects:add_user' tenant_id user_id %}{% endblock %}
-
-{% block modal_id %}add_user_modal{% endblock %}
-{% block modal-header %}{% trans "Add User To Project" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "Select the user role for the project." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Add" %}" />
- <a href="{% url 'horizon:admin:projects:users' tenant_id %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/_create.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/_create.html
deleted file mode 100644
index 59c13c57..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/_create.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_tenant_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:projects:create' %}{% endblock %}
-
-{% block modal_id %}create_tenant_modal{% endblock %}
-{% block modal-header %}{% trans "Create Project" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can create a new project to organize users." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Project" %}" />
- <a href="{% url 'horizon:admin:projects:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/_create_user.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/_create_user.html
deleted file mode 100644
index 483e73ae..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/_create_user.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_user_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:projects:create_user' tenant_id %}{% endblock %}
-
-{% block modal-header %}{% blocktrans %}Create User for project '{{ tenant_name }}'.{% endblocktrans %}{% endblock %}
-
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can create a new user to add to this project." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create User" %}" />
- <a href="{% url 'horizon:admin:projects:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/_quotas.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/_quotas.html
deleted file mode 100644
index a11890f9..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/_quotas.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}quota_update_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:projects:quotas' tenant.id %}{% endblock %}
-
-{% block modal-header %}{% trans "Update Quota" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% blocktrans with tenant_id=tenant.id %}From here you can edit quotas (max limits) for the project {{ tenant.name }}.{% endblocktrans %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Update Quota" %}" />
- <a href="{% url 'horizon:admin:projects:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/_update.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/_update.html
deleted file mode 100644
index afb15480..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/_update.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}{% endblock %}
-{% block form_action %}{% url 'horizon:admin:projects:update' tenant.id %}{% endblock %}
-
-{% block modal_id %}update_tenant_modal{% endblock %}
-{% block modal-header %}{% trans "Update Project" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can edit a project." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Update Project" %}" />
- <a href="{% url 'horizon:admin:projects:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/_update_members.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/_update_members.html
deleted file mode 100644
index 4762c7b7..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/_update_members.html
+++ /dev/null
@@ -1,39 +0,0 @@
-{% load i18n %}
-
-<noscript><h3>{{ step }}</h3></noscript>
-
-<div class="project_membership">
- <div class="header">
- <div class="help_text">{% trans "From here you can add and remove members to this project from the list of all available users." %}</div>
- <div class="left">
- <div class="fake_table fake_table_header">
- <span class="users_title">{% trans "All Users" %}</span>
- <input type="text" name="available_users_filter" id="available_users" class="filter" value="Filter">
- </div>
- </div>
- <div class="right">
- <div class="fake_table fake_table_header">
- <span class="users_title">{% trans "Project Members" %}</span>
- <input type="text" name="project_members_filter" id="project_members" class="filter" value="Filter">
- </div>
- </div>
- </div>
-
- <div class="left filterable">
- <div class="fake_table" id="available_users">
- <ul class="available_users"></ul>
- <ul class="no_results" id="no_available_users"><li>{% trans "No users found." %}</li></ul>
- </div>
- </div>
-
- <div class="right filterable">
- <div class="fake_table" id="project_members">
- <ul class="project_members"></ul>
- <ul class="no_results" id="no_project_members"><li>{% trans "No users found." %}</li></ul>
- </div>
- </div>
-</div>
-
-<div class="hide">
- {% include "horizon/common/_form_fields.html" %}
-</div>
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/add_user.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/add_user.html
deleted file mode 100644
index 53618120..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/add_user.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Add User To Project" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Add User To Project") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/projects/_add_user.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/create_user.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/create_user.html
deleted file mode 100644
index 306bf669..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/create_user.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Add New User" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Add New User") %}
-{% endblock page_header %}
-
-
-{% block main %}
- {% include 'horizon/common/_create_user.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/index.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/index.html
deleted file mode 100644
index 1391c3c0..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Projects" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_domain_page_header.html" with title=_("Projects") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/quotas.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/quotas.html
deleted file mode 100644
index da1fb729..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/quotas.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Modify Project Quotas" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Update Project") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/projects/_quotas.html' with form=form %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/usage.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/usage.html
deleted file mode 100644
index 0a71273d..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/usage.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n sizeformat %}
-{% block title %}{% trans "Project Usage Overview" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_domain_page_header.html" with title=_("Project Usage") %}
-{% endblock %}
-
-{% block main %}
- {% include "horizon/common/_usage_summary.html" %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/projects/templates/projects/users.html b/openstack_dashboard/dashboards/admin/projects/templates/projects/users.html
deleted file mode 100644
index be24ce88..00000000
--- a/openstack_dashboard/dashboards/admin/projects/templates/projects/users.html
+++ /dev/null
@@ -1,18 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Project Users" %}{% endblock %}
-
-{% block page_header %}
- <div class='page-header'>
- <h2>{% trans "Users for Project" %}: <span>{{ tenant.name }}</span></h2>
- </div>
-{% endblock %}
-
-{% block main %}
- <div id="tenant_users_table">
- {{ tenant_users_table.render }}
- </div>
- <div id="add_users_table">
- {{ add_users_table.render }}
- </div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/projects/tests.py b/openstack_dashboard/dashboards/admin/projects/tests.py
deleted file mode 100644
index a571424e..00000000
--- a/openstack_dashboard/dashboards/admin/projects/tests.py
+++ /dev/null
@@ -1,1069 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from horizon import exceptions
-from horizon.workflows.views import WorkflowView
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-from openstack_dashboard.usage import quotas
-
-from openstack_dashboard.dashboards.admin.projects.workflows \
- import CreateProject
-from openstack_dashboard.dashboards.admin.projects.workflows \
- import UpdateProject
-
-INDEX_URL = reverse('horizon:admin:projects:index')
-
-
-@test.create_stubs({api.keystone: ('tenant_list',)})
-class TenantsViewTests(test.BaseAdminViewTests):
- def test_index(self):
- api.keystone.tenant_list(IsA(http.HttpRequest),
- domain=None,
- paginate=True) \
- .AndReturn([self.tenants.list(), False])
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
- self.assertTemplateUsed(res, 'admin/projects/index.html')
- self.assertItemsEqual(res.context['table'].data, self.tenants.list())
-
- @test.create_stubs({api.keystone: ('tenant_list', )})
- def test_index_with_domain_context(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- domain_tenants = [tenant for tenant in self.tenants.list()
- if tenant.domain_id == domain.id]
- api.keystone.tenant_list(IsA(http.HttpRequest),
- domain=domain.id) \
- .AndReturn(domain_tenants)
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
- self.assertTemplateUsed(res, 'admin/projects/index.html')
- self.assertItemsEqual(res.context['table'].data, domain_tenants)
- self.assertContains(res, "<em>test_domain:</em>")
-
-
-class CreateProjectWorkflowTests(test.BaseAdminViewTests):
- def _get_project_info(self, project):
- domain_id = self.request.session.get('domain_context', None)
- project_info = {"name": project.name,
- "description": project.description,
- "enabled": project.enabled,
- "domain": domain_id}
- return project_info
-
- def _get_workflow_fields(self, project):
- project_info = {"name": project.name,
- "description": project.description,
- "enabled": project.enabled}
- return project_info
-
- def _get_quota_info(self, quota):
- cinder_quota = self.cinder_quotas.first()
- quota_data = {}
- for field in quotas.NOVA_QUOTA_FIELDS:
- quota_data[field] = int(quota.get(field).limit)
- for field in quotas.CINDER_QUOTA_FIELDS:
- quota_data[field] = int(cinder_quota.get(field).limit)
- return quota_data
-
- def _get_workflow_data(self, project, quota):
- project_info = self._get_workflow_fields(project)
- quota_data = self._get_quota_info(quota)
- project_info.update(quota_data)
- return project_info
-
- def _get_domain_id(self):
- return self.request.session.get('domain_context', None)
-
- def _get_all_users(self, domain_id):
- if not domain_id:
- users = self.users.list()
- else:
- users = [user for user in self.users.list()
- if user.domain_id == domain_id]
- return users
-
- @test.create_stubs({api.keystone: ('get_default_role',
- 'user_list',
- 'role_list'),
- quotas: ('get_default_quota_data',)})
- def test_add_project_get(self):
- quota = self.quotas.first()
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- roles = self.roles.list()
-
- quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)
-
- # init
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:projects:create')
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- workflow = res.context['workflow']
- self.assertEqual(res.context['workflow'].name, CreateProject.name)
-
- step = workflow.get_step("createprojectinfoaction")
- self.assertEqual(step.action.initial['ram'], quota.get('ram').limit)
- self.assertEqual(step.action.initial['injected_files'],
- quota.get('injected_files').limit)
- self.assertQuerysetEqual(workflow.steps,
- ['<CreateProjectInfo: createprojectinfoaction>',
- '<UpdateProjectMembers: update_members>',
- '<UpdateProjectQuota: update_quotas>'])
-
- def test_add_project_get_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_add_project_get()
-
- @test.create_stubs({api.keystone: ('get_default_role',
- 'add_tenant_user_role',
- 'tenant_create',
- 'user_list',
- 'role_list'),
- quotas: ('get_default_quota_data',),
- api.cinder: ('tenant_quota_update',),
- api.nova: ('tenant_quota_update',)})
- def test_add_project_post(self):
- project = self.tenants.first()
- quota = self.quotas.first()
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- roles = self.roles.list()
-
- # init
- quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # contribute
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # handle
- project_details = self._get_project_info(project)
- quota_data = self._get_quota_info(quota)
-
- api.keystone.tenant_create(IsA(http.HttpRequest), **project_details) \
- .AndReturn(project)
-
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- workflow_data = {}
- for role in roles:
- if "role_" + role.id in workflow_data:
- ulist = workflow_data["role_" + role.id]
- for user_id in ulist:
- api.keystone.add_tenant_user_role(IsA(http.HttpRequest),
- project=self.tenant.id,
- user=user_id,
- role=role.id)
-
- nova_updated_quota = dict([(key, quota_data[key]) for key in
- quotas.NOVA_QUOTA_FIELDS])
- api.nova.tenant_quota_update(IsA(http.HttpRequest),
- project.id,
- **nova_updated_quota)
- cinder_updated_quota = dict([(key, quota_data[key]) for key in
- quotas.CINDER_QUOTA_FIELDS])
- api.cinder.tenant_quota_update(IsA(http.HttpRequest),
- project.id,
- **cinder_updated_quota)
-
- self.mox.ReplayAll()
-
- workflow_data.update(self._get_workflow_data(project, quota))
-
- url = reverse('horizon:admin:projects:create')
- res = self.client.post(url, workflow_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_add_project_post_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_add_project_post()
-
- @test.create_stubs({api.keystone: ('user_list',
- 'role_list',
- 'get_default_role'),
- quotas: ('get_default_quota_data',)})
- def test_add_project_quota_defaults_error(self):
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- roles = self.roles.list()
-
- # init
- quotas.get_default_quota_data(IsA(http.HttpRequest)) \
- .AndRaise(self.exceptions.nova)
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:projects:create')
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, WorkflowView.template_name)
- self.assertContains(res, "Unable to retrieve default quota values")
-
- def test_add_project_quota_defaults_error_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_add_project_quota_defaults_error()
-
- @test.create_stubs({api.keystone: ('tenant_create',
- 'user_list',
- 'role_list',
- 'get_default_role'),
- quotas: ('get_default_quota_data',)})
- def test_add_project_tenant_create_error(self):
- project = self.tenants.first()
- quota = self.quotas.first()
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- roles = self.roles.list()
-
- # init
- quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # contribute
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # handle
- project_details = self._get_project_info(project)
-
- api.keystone.tenant_create(IsA(http.HttpRequest), **project_details) \
- .AndRaise(self.exceptions.keystone)
-
- self.mox.ReplayAll()
-
- workflow_data = self._get_workflow_data(project, quota)
-
- url = reverse('horizon:admin:projects:create')
- res = self.client.post(url, workflow_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_add_project_tenant_create_error_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_add_project_tenant_create_error()
-
- @test.create_stubs({api.keystone: ('tenant_create',
- 'user_list',
- 'role_list',
- 'get_default_role',
- 'add_tenant_user_role'),
- quotas: ('get_default_quota_data',),
- api.nova: ('tenant_quota_update',)})
- def test_add_project_quota_update_error(self):
- project = self.tenants.first()
- quota = self.quotas.first()
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- roles = self.roles.list()
-
- # init
- quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # contribute
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # handle
- project_details = self._get_project_info(project)
- quota_data = self._get_quota_info(quota)
-
- api.keystone.tenant_create(IsA(http.HttpRequest), **project_details) \
- .AndReturn(project)
-
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- workflow_data = {}
- for role in roles:
- if "role_" + role.id in workflow_data:
- ulist = workflow_data["role_" + role.id]
- for user_id in ulist:
- api.keystone.add_tenant_user_role(IsA(http.HttpRequest),
- project=self.tenant.id,
- user=user_id,
- role=role.id)
-
- nova_updated_quota = dict([(key, quota_data[key]) for key in
- quotas.NOVA_QUOTA_FIELDS])
- api.nova.tenant_quota_update(IsA(http.HttpRequest),
- project.id,
- **nova_updated_quota) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- workflow_data.update(self._get_workflow_data(project, quota))
-
- url = reverse('horizon:admin:projects:create')
- res = self.client.post(url, workflow_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_add_project_quota_update_error_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_add_project_quota_update_error()
-
- @test.create_stubs({api.keystone: ('tenant_create',
- 'user_list',
- 'role_list',
- 'get_default_role',
- 'add_tenant_user_role'),
- quotas: ('get_default_quota_data',),
- api.cinder: ('tenant_quota_update',),
- api.nova: ('tenant_quota_update',)})
- def test_add_project_user_update_error(self):
- project = self.tenants.first()
- quota = self.quotas.first()
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- roles = self.roles.list()
-
- # init
- quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # contribute
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # handle
- project_details = self._get_project_info(project)
- quota_data = self._get_quota_info(quota)
-
- api.keystone.tenant_create(IsA(http.HttpRequest), **project_details) \
- .AndReturn(project)
-
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- workflow_data = {}
- for role in roles:
- if "role_" + role.id in workflow_data:
- ulist = workflow_data["role_" + role.id]
- for user_id in ulist:
- api.keystone.add_tenant_user_role(IsA(http.HttpRequest),
- project=self.tenant.id,
- user=user_id,
- role=role.id) \
- .AndRaise(self.exceptions.keystone)
- break
- break
-
- nova_updated_quota = dict([(key, quota_data[key]) for key in
- quotas.NOVA_QUOTA_FIELDS])
- api.nova.tenant_quota_update(IsA(http.HttpRequest),
- project.id,
- **nova_updated_quota)
-
- cinder_updated_quota = dict([(key, quota_data[key]) for key in
- quotas.CINDER_QUOTA_FIELDS])
- api.cinder.tenant_quota_update(IsA(http.HttpRequest),
- project.id,
- **cinder_updated_quota)
-
- self.mox.ReplayAll()
-
- workflow_data.update(self._get_workflow_data(project, quota))
-
- url = reverse('horizon:admin:projects:create')
- res = self.client.post(url, workflow_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_add_project_user_update_error_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_add_project_user_update_error()
-
- @test.create_stubs({api.keystone: ('user_list',
- 'role_list',
- 'get_default_role'),
- quotas: ('get_default_quota_data',)})
- def test_add_project_missing_field_error(self):
- project = self.tenants.first()
- quota = self.quotas.first()
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- roles = self.roles.list()
-
- # init
- quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # contribute
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- self.mox.ReplayAll()
-
- workflow_data = self._get_workflow_data(project, quota)
- workflow_data["name"] = ""
-
- url = reverse('horizon:admin:projects:create')
- res = self.client.post(url, workflow_data)
-
- self.assertContains(res, "field is required")
-
- def test_add_project_missing_field_error_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_add_project_missing_field_error()
-
-
-class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
- def _get_quota_info(self, quota):
- cinder_quota = self.cinder_quotas.first()
- quota_data = {}
- for field in quotas.NOVA_QUOTA_FIELDS:
- quota_data[field] = int(quota.get(field).limit)
- for field in quotas.CINDER_QUOTA_FIELDS:
- quota_data[field] = int(cinder_quota.get(field).limit)
- return quota_data
-
- def _get_domain_id(self):
- return self.request.session.get('domain_context', None)
-
- def _get_all_users(self, domain_id):
- if not domain_id:
- users = self.users.list()
- else:
- users = [user for user in self.users.list()
- if user.domain_id == domain_id]
- return users
-
- def _get_proj_users(self, project_id):
- return [user for user in self.users.list()
- if user.project_id == project_id]
-
- @test.create_stubs({api.keystone: ('get_default_role',
- 'roles_for_user',
- 'tenant_get',
- 'user_list',
- 'role_list'),
- quotas: ('get_tenant_quota_data',)})
- def test_update_project_get(self):
- project = self.tenants.first()
- quota = self.quotas.first()
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- roles = self.roles.list()
-
- api.keystone.tenant_get(IsA(http.HttpRequest),
- self.tenant.id, admin=True) \
- .AndReturn(project)
- quotas.get_tenant_quota_data(IsA(http.HttpRequest),
- tenant_id=self.tenant.id) \
- .AndReturn(quota)
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- for user in users:
- api.keystone.roles_for_user(IsA(http.HttpRequest),
- user.id,
- self.tenant.id).AndReturn(roles)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:projects:update',
- args=[self.tenant.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- workflow = res.context['workflow']
- self.assertEqual(res.context['workflow'].name, UpdateProject.name)
-
- step = workflow.get_step("update_info")
- self.assertEqual(step.action.initial['ram'], quota.get('ram').limit)
- self.assertEqual(step.action.initial['injected_files'],
- quota.get('injected_files').limit)
- self.assertEqual(step.action.initial['name'], project.name)
- self.assertEqual(step.action.initial['description'],
- project.description)
- self.assertQuerysetEqual(workflow.steps,
- ['<UpdateProjectInfo: update_info>',
- '<UpdateProjectMembers: update_members>',
- '<UpdateProjectQuota: update_quotas>'])
-
- def test_update_project_get_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_update_project_get()
-
- @test.create_stubs({api.keystone: ('tenant_get',
- 'tenant_update',
- 'get_default_role',
- 'roles_for_user',
- 'remove_tenant_user_role',
- 'add_tenant_user_role',
- 'user_list',
- 'role_list'),
- api.nova: ('tenant_quota_update',),
- api.cinder: ('tenant_quota_update',),
- quotas: ('get_tenant_quota_data',)})
- def test_update_project_save(self):
- project = self.tenants.first()
- quota = self.quotas.first()
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- proj_users = self._get_proj_users(project.id)
- roles = self.roles.list()
-
- # get/init
- api.keystone.tenant_get(IsA(http.HttpRequest),
- self.tenant.id, admin=True) \
- .AndReturn(project)
- quotas.get_tenant_quota_data(IsA(http.HttpRequest),
- tenant_id=self.tenant.id) \
- .AndReturn(quota)
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- workflow_data = {}
- for user in users:
- api.keystone.roles_for_user(IsA(http.HttpRequest),
- user.id,
- self.tenant.id).AndReturn(roles)
-
- workflow_data["role_1"] = ['3'] # admin role
- workflow_data["role_2"] = ['2'] # member role
-
- # update some fields
- project._info["name"] = "updated name"
- project._info["description"] = "updated description"
- quota.metadata_items = 444
- quota.volumes = 444
-
- updated_project = {"name": project._info["name"],
- "description": project._info["description"],
- "enabled": project.enabled}
- updated_quota = self._get_quota_info(quota)
-
- # contribute
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # handle
- api.keystone.tenant_update(IsA(http.HttpRequest),
- project.id,
- **updated_project) \
- .AndReturn(project)
-
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
- api.keystone.user_list(IsA(http.HttpRequest),
- project=self.tenant.id).AndReturn(proj_users)
-
- # admin user - try to remove all roles on current project, warning
- api.keystone.roles_for_user(IsA(http.HttpRequest), '1',
- self.tenant.id) \
- .AndReturn(roles)
-
- # member user 1 - has role 1, will remove it
- api.keystone.roles_for_user(IsA(http.HttpRequest), '2',
- self.tenant.id) \
- .AndReturn((roles[0],))
- # remove role 1
- api.keystone.remove_tenant_user_role(IsA(http.HttpRequest),
- project=self.tenant.id,
- user='2',
- role='1')
- # add role 2
- api.keystone.add_tenant_user_role(IsA(http.HttpRequest),
- project=self.tenant.id,
- user='2',
- role='2')
-
- # member user 3 - has role 2
- api.keystone.roles_for_user(IsA(http.HttpRequest), '3',
- self.tenant.id) \
- .AndReturn((roles[1],))
- # remove role 2
- api.keystone.remove_tenant_user_role(IsA(http.HttpRequest),
- project=self.tenant.id,
- user='3',
- role='2')
- # add role 1
- api.keystone.add_tenant_user_role(IsA(http.HttpRequest),
- project=self.tenant.id,
- user='3',
- role='1')
-
- nova_updated_quota = dict([(key, updated_quota[key]) for key in
- quotas.NOVA_QUOTA_FIELDS])
- api.nova.tenant_quota_update(IsA(http.HttpRequest),
- project.id,
- **nova_updated_quota)
-
- cinder_updated_quota = dict([(key, updated_quota[key]) for key in
- quotas.CINDER_QUOTA_FIELDS])
- api.cinder.tenant_quota_update(IsA(http.HttpRequest),
- project.id,
- **cinder_updated_quota)
- self.mox.ReplayAll()
-
- # submit form data
- project_data = {"name": project._info["name"],
- "id": project.id,
- "description": project._info["description"],
- "enabled": project.enabled}
- workflow_data.update(project_data)
- workflow_data.update(updated_quota)
- url = reverse('horizon:admin:projects:update',
- args=[self.tenant.id])
- res = self.client.post(url, workflow_data)
-
- self.assertNoFormErrors(res)
- self.assertMessageCount(error=0, warning=1)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_update_project_save_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_update_project_save()
-
- @test.create_stubs({api.keystone: ('tenant_get',)})
- def test_update_project_get_error(self):
-
- api.keystone.tenant_get(IsA(http.HttpRequest), self.tenant.id,
- admin=True) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:projects:update',
- args=[self.tenant.id])
- res = self.client.get(url)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.keystone: ('tenant_get',
- 'tenant_update',
- 'get_default_role',
- 'roles_for_user',
- 'remove_tenant_user',
- 'add_tenant_user_role',
- 'user_list',
- 'role_list'),
- quotas: ('get_tenant_quota_data',),
- api.nova: ('tenant_quota_update',)})
- def test_update_project_tenant_update_error(self):
- project = self.tenants.first()
- quota = self.quotas.first()
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- roles = self.roles.list()
-
- # get/init
- api.keystone.tenant_get(IsA(http.HttpRequest), self.tenant.id,
- admin=True) \
- .AndReturn(project)
- quotas.get_tenant_quota_data(IsA(http.HttpRequest),
- tenant_id=self.tenant.id) \
- .AndReturn(quota)
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- workflow_data = {}
- for user in users:
- api.keystone.roles_for_user(IsA(http.HttpRequest),
- user.id,
- self.tenant.id).AndReturn(roles)
- role_ids = [role.id for role in roles]
- if role_ids:
- workflow_data.setdefault("role_" + role_ids[0], []) \
- .append(user.id)
-
- # update some fields
- project._info["name"] = "updated name"
- project._info["description"] = "updated description"
- quota.metadata_items = 444
- quota.volumes = 444
-
- updated_project = {"name": project._info["name"],
- "description": project._info["description"],
- "enabled": project.enabled}
- updated_quota = self._get_quota_info(quota)
-
- # contribute
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # handle
- api.keystone.tenant_update(IsA(http.HttpRequest),
- project.id,
- **updated_project) \
- .AndRaise(self.exceptions.keystone)
-
- self.mox.ReplayAll()
-
- # submit form data
- project_data = {"name": project._info["name"],
- "id": project.id,
- "description": project._info["description"],
- "enabled": project.enabled}
- workflow_data.update(project_data)
- workflow_data.update(updated_quota)
- url = reverse('horizon:admin:projects:update',
- args=[self.tenant.id])
- res = self.client.post(url, workflow_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_update_project_tenant_update_error_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_update_project_tenant_update_error()
-
- @test.create_stubs({api.keystone: ('tenant_get',
- 'tenant_update',
- 'get_default_role',
- 'roles_for_user',
- 'remove_tenant_user_role',
- 'add_tenant_user_role',
- 'user_list',
- 'role_list'),
- quotas: ('get_tenant_quota_data',),
- api.nova: ('tenant_quota_update',)})
- def test_update_project_quota_update_error(self):
- project = self.tenants.first()
- quota = self.quotas.first()
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- proj_users = self._get_proj_users(project.id)
- roles = self.roles.list()
-
- # get/init
- api.keystone.tenant_get(IsA(http.HttpRequest), self.tenant.id,
- admin=True) \
- .AndReturn(project)
- quotas.get_tenant_quota_data(IsA(http.HttpRequest),
- tenant_id=self.tenant.id) \
- .AndReturn(quota)
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- workflow_data = {}
-
- for user in users:
- api.keystone.roles_for_user(IsA(http.HttpRequest),
- user.id,
- self.tenant.id).AndReturn(roles)
-
- workflow_data["role_1"] = ['1', '3'] # admin role
- workflow_data["role_2"] = ['1', '2', '3'] # member role
-
- # update some fields
- project._info["name"] = "updated name"
- project._info["description"] = "updated description"
- quota[0].limit = 444
- quota[1].limit = -1
-
- updated_project = {"name": project._info["name"],
- "description": project._info["description"],
- "enabled": project.enabled}
- updated_quota = self._get_quota_info(quota)
-
- # contribute
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # handle
- # handle
- api.keystone.tenant_update(IsA(http.HttpRequest),
- project.id,
- **updated_project) \
- .AndReturn(project)
-
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
- api.keystone.user_list(IsA(http.HttpRequest),
- project=self.tenant.id).AndReturn(proj_users)
-
- # admin user - try to remove all roles on current project, warning
- api.keystone.roles_for_user(IsA(http.HttpRequest), '1',
- self.tenant.id) \
- .AndReturn(roles)
-
- # member user 1 - has role 1, will remove it
- api.keystone.roles_for_user(IsA(http.HttpRequest), '2',
- self.tenant.id) \
- .AndReturn((roles[1],))
-
- # member user 3 - has role 2
- api.keystone.roles_for_user(IsA(http.HttpRequest), '3',
- self.tenant.id) \
- .AndReturn((roles[0],))
- # add role 2
- api.keystone.add_tenant_user_role(IsA(http.HttpRequest),
- project=self.tenant.id,
- user='3',
- role='2')
-
- nova_updated_quota = dict([(key, updated_quota[key]) for key in
- quotas.NOVA_QUOTA_FIELDS])
- api.nova.tenant_quota_update(IsA(http.HttpRequest),
- project.id,
- **nova_updated_quota) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- # submit form data
- project_data = {"name": project._info["name"],
- "id": project.id,
- "description": project._info["description"],
- "enabled": project.enabled}
- workflow_data.update(project_data)
- workflow_data.update(updated_quota)
- url = reverse('horizon:admin:projects:update',
- args=[self.tenant.id])
- res = self.client.post(url, workflow_data)
-
- self.assertNoFormErrors(res)
- self.assertMessageCount(error=1, warning=0)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_update_project_quota_update_error_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_update_project_quota_update_error()
-
- @test.create_stubs({api.keystone: ('tenant_get',
- 'tenant_update',
- 'get_default_role',
- 'roles_for_user',
- 'remove_tenant_user_role',
- 'add_tenant_user_role',
- 'user_list',
- 'role_list'),
- quotas: ('get_tenant_quota_data',)})
- def test_update_project_member_update_error(self):
- project = self.tenants.first()
- quota = self.quotas.first()
- default_role = self.roles.first()
- domain_id = self._get_domain_id()
- users = self._get_all_users(domain_id)
- proj_users = self._get_proj_users(project.id)
- roles = self.roles.list()
-
- # get/init
- api.keystone.tenant_get(IsA(http.HttpRequest), self.tenant.id,
- admin=True) \
- .AndReturn(project)
- quotas.get_tenant_quota_data(IsA(http.HttpRequest),
- tenant_id=self.tenant.id) \
- .AndReturn(quota)
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(default_role)
- api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \
- .AndReturn(users)
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- workflow_data = {}
- for user in users:
- api.keystone.roles_for_user(IsA(http.HttpRequest),
- user.id,
- self.tenant.id).AndReturn(roles)
- workflow_data["role_1"] = ['1', '3'] # admin role
- workflow_data["role_2"] = ['1', '2', '3'] # member role
-
- # update some fields
- project._info["name"] = "updated name"
- project._info["description"] = "updated description"
- quota.metadata_items = 444
- quota.volumes = 444
-
- updated_project = {"name": project._info["name"],
- "description": project._info["description"],
- "enabled": project.enabled}
- updated_quota = self._get_quota_info(quota)
-
- # contribute
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
-
- # handle
- api.keystone.tenant_update(IsA(http.HttpRequest),
- project.id,
- **updated_project) \
- .AndReturn(project)
-
- api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)
- api.keystone.user_list(IsA(http.HttpRequest),
- project=self.tenant.id).AndReturn(proj_users)
-
- # admin user - try to remove all roles on current project, warning
- api.keystone.roles_for_user(IsA(http.HttpRequest), '1',
- self.tenant.id).AndReturn(roles)
-
- # member user 1 - has role 1, will remove it
- api.keystone.roles_for_user(IsA(http.HttpRequest), '2',
- self.tenant.id).AndReturn((roles[1],))
-
- # member user 3 - has role 2
- api.keystone.roles_for_user(IsA(http.HttpRequest), '3',
- self.tenant.id).AndReturn((roles[0],))
- # add role 2
- api.keystone.add_tenant_user_role(IsA(http.HttpRequest),
- project=self.tenant.id,
- user='3',
- role='2')\
- .AndRaise(self.exceptions.keystone)
-
- self.mox.ReplayAll()
-
- # submit form data
- project_data = {"name": project._info["name"],
- "id": project.id,
- "description": project._info["description"],
- "enabled": project.enabled}
- workflow_data.update(project_data)
- workflow_data.update(updated_quota)
- url = reverse('horizon:admin:projects:update',
- args=[self.tenant.id])
- res = self.client.post(url, workflow_data)
-
- self.assertNoFormErrors(res)
- self.assertMessageCount(error=1, warning=0)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_update_project_member_update_error_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_update_project_member_update_error()
-
- @test.create_stubs({api.keystone: ('get_default_role', 'tenant_get'),
- quotas: ('get_tenant_quota_data',)})
- def test_update_project_when_default_role_does_not_exist(self):
- project = self.tenants.first()
- quota = self.quotas.first()
-
- api.keystone.get_default_role(IsA(http.HttpRequest)) \
- .AndReturn(None) # Default role doesn't exist
- api.keystone.tenant_get(IsA(http.HttpRequest), self.tenant.id,
- admin=True) \
- .AndReturn(project)
- quotas.get_tenant_quota_data(IsA(http.HttpRequest),
- tenant_id=self.tenant.id) \
- .AndReturn(quota)
- self.mox.ReplayAll()
-
- url = reverse('horizon:admin:projects:update',
- args=[self.tenant.id])
-
- try:
- # Avoid the log message in the test output when the workflow's
- # step action cannot be instantiated
- logging.disable(logging.ERROR)
- with self.assertRaises(exceptions.NotFound):
- self.client.get(url)
- finally:
- logging.disable(logging.NOTSET)
diff --git a/openstack_dashboard/dashboards/admin/projects/urls.py b/openstack_dashboard/dashboards/admin/projects/urls.py
deleted file mode 100644
index 9b294a56..00000000
--- a/openstack_dashboard/dashboards/admin/projects/urls.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.projects.views \
- import CreateProjectView
-from openstack_dashboard.dashboards.admin.projects.views import CreateUserView
-from openstack_dashboard.dashboards.admin.projects.views import IndexView
-from openstack_dashboard.dashboards.admin.projects.views \
- import ProjectUsageView
-from openstack_dashboard.dashboards.admin.projects.views \
- import UpdateProjectView
-
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^create$', CreateProjectView.as_view(), name='create'),
- url(r'^(?P<tenant_id>[^/]+)/update/$',
- UpdateProjectView.as_view(), name='update'),
- url(r'^(?P<tenant_id>[^/]+)/usage/$',
- ProjectUsageView.as_view(), name='usage'),
- url(r'^(?P<tenant_id>[^/]+)/create_user/$',
- CreateUserView.as_view(), name='create_user'),
-)
diff --git a/openstack_dashboard/dashboards/admin/projects/views.py b/openstack_dashboard/dashboards/admin/projects/views.py
deleted file mode 100644
index dcc27639..00000000
--- a/openstack_dashboard/dashboards/admin/projects/views.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-from horizon import workflows
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.admin.users.views import CreateView
-from openstack_dashboard import usage
-from openstack_dashboard.usage import quotas
-
-from openstack_dashboard.dashboards.admin.projects.forms import CreateUser
-from openstack_dashboard.dashboards.admin.projects.tables import AddUsersTable
-from openstack_dashboard.dashboards.admin.projects.tables import TenantsTable
-from openstack_dashboard.dashboards.admin.projects.tables \
- import TenantUsersTable
-from openstack_dashboard.dashboards.admin.projects.workflows \
- import CreateProject
-from openstack_dashboard.dashboards.admin.projects.workflows \
- import UpdateProject
-
-LOG = logging.getLogger(__name__)
-
-PROJECT_INFO_FIELDS = ("name",
- "description",
- "enabled")
-
-INDEX_URL = "horizon:admin:projects:index"
-
-
-class TenantContextMixin(object):
- def get_object(self):
- if not hasattr(self, "_object"):
- tenant_id = self.kwargs['tenant_id']
- try:
- self._object = api.keystone.tenant_get(self.request,
- tenant_id,
- admin=True)
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve project information.'),
- redirect=reverse(INDEX_URL))
- return self._object
-
- def get_context_data(self, **kwargs):
- context = super(TenantContextMixin, self).get_context_data(**kwargs)
- context['tenant'] = self.get_object()
- return context
-
-
-class IndexView(tables.DataTableView):
- table_class = TenantsTable
- template_name = 'admin/projects/index.html'
-
- def has_more_data(self, table):
- return self._more
-
- def get_data(self):
- tenants = []
- marker = self.request.GET.get(
- TenantsTable._meta.pagination_param, None)
- domain_context = self.request.session.get('domain_context', None)
- try:
- tenants, self._more = api.keystone.tenant_list(
- self.request,
- domain=domain_context,
- paginate=True,
- marker=marker)
- except:
- self._more = False
- exceptions.handle(self.request,
- _("Unable to retrieve project list."))
- return tenants
-
-
-class UsersView(tables.MultiTableView):
- table_classes = (TenantUsersTable, AddUsersTable)
- template_name = 'admin/projects/users.html'
-
- def _get_shared_data(self, *args, **kwargs):
- tenant_id = self.kwargs["tenant_id"]
- if not hasattr(self, "_shared_data"):
- domain_context = self.request.session.get('domain_context', None)
- try:
- tenant = api.keystone.tenant_get(self.request,
- tenant_id,
- admin=True)
- all_users = api.keystone.user_list(self.request,
- domain=domain_context)
- tenant_users = api.keystone.user_list(self.request, tenant_id)
- self._shared_data = {'tenant': tenant,
- 'all_users': all_users,
- 'tenant_users': tenant_users}
- except:
- exceptions.handle(self.request,
- _("Unable to retrieve users."),
- redirect=reverse(INDEX_URL))
- return self._shared_data
-
- def get_tenant_users_data(self):
- return self._get_shared_data()["tenant_users"]
-
- def get_add_users_data(self):
- tenant_users = self._get_shared_data()["tenant_users"]
- all_users = self._get_shared_data()["all_users"]
- tenant_user_ids = [user.id for user in tenant_users]
- return filter(lambda u: u.id not in tenant_user_ids, all_users)
-
- def get_context_data(self, **kwargs):
- context = super(UsersView, self).get_context_data(**kwargs)
- context['tenant'] = self._get_shared_data()["tenant"]
- return context
-
-
-class ProjectUsageView(usage.UsageView):
- table_class = usage.ProjectUsageTable
- usage_class = usage.ProjectUsage
- template_name = 'admin/projects/usage.html'
-
- def get_data(self):
- super(ProjectUsageView, self).get_data()
- return self.usage.get_instances()
-
-
-class CreateProjectView(workflows.WorkflowView):
- workflow_class = CreateProject
-
- def get_initial(self):
- initial = super(CreateProjectView, self).get_initial()
-
- # get initial quota defaults
- try:
- quota_defaults = quotas.get_default_quota_data(self.request)
- for field in quotas.QUOTA_FIELDS:
- initial[field] = quota_defaults.get(field).limit
-
- except:
- error_msg = _('Unable to retrieve default quota values.')
- self.add_error_to_step(error_msg, 'update_quotas')
-
- return initial
-
-
-class UpdateProjectView(workflows.WorkflowView):
- workflow_class = UpdateProject
-
- def get_initial(self):
- initial = super(UpdateProjectView, self).get_initial()
-
- project_id = self.kwargs['tenant_id']
- initial['project_id'] = project_id
-
- try:
- # get initial project info
- project_info = api.keystone.tenant_get(self.request, project_id,
- admin=True)
- for field in PROJECT_INFO_FIELDS:
- initial[field] = getattr(project_info, field, None)
-
- # get initial project quota
- quota_data = quotas.get_tenant_quota_data(self.request,
- tenant_id=project_id)
- for field in quotas.QUOTA_FIELDS:
- initial[field] = quota_data.get(field).limit
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve project details.'),
- redirect=reverse(INDEX_URL))
- return initial
-
-
-class CreateUserView(CreateView):
- form_class = CreateUser
- template_name = "admin/projects/create_user.html"
- success_url = reverse_lazy('horizon:admin:projects:index')
-
- def get_initial(self):
- default_role = api.keystone.get_default_role(self.request)
- return {'role_id': getattr(default_role, "id", None),
- 'project': self.kwargs['tenant_id']}
-
- def get_context_data(self, **kwargs):
- context = super(CreateUserView, self).get_context_data(**kwargs)
- context['tenant_id'] = self.kwargs['tenant_id']
- context['tenant_name'] = api.keystone.tenant_get(
- self.request,
- self.kwargs['tenant_id'],
- admin=True).name
- return context
diff --git a/openstack_dashboard/dashboards/admin/projects/workflows.py b/openstack_dashboard/dashboards/admin/projects/workflows.py
deleted file mode 100644
index 7dce9bc6..00000000
--- a/openstack_dashboard/dashboards/admin/projects/workflows.py
+++ /dev/null
@@ -1,428 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-from django.conf import settings
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-from horizon import workflows
-
-from openstack_dashboard import api
-from openstack_dashboard.api.base import is_service_enabled
-from openstack_dashboard.api import cinder
-from openstack_dashboard.api import nova
-from openstack_dashboard.usage.quotas import CINDER_QUOTA_FIELDS
-from openstack_dashboard.usage.quotas import get_disabled_quotas
-from openstack_dashboard.usage.quotas import NOVA_QUOTA_FIELDS
-from openstack_dashboard.usage.quotas import QUOTA_FIELDS
-
-INDEX_URL = "horizon:admin:projects:index"
-ADD_USER_URL = "horizon:admin:projects:create_user"
-
-
-class UpdateProjectQuotaAction(workflows.Action):
- ifcb_label = _("Injected File Content Bytes")
- metadata_items = forms.IntegerField(min_value=-1,
- label=_("Metadata Items"))
- cores = forms.IntegerField(min_value=-1, label=_("VCPUs"))
- instances = forms.IntegerField(min_value=-1, label=_("Instances"))
- injected_files = forms.IntegerField(min_value=-1,
- label=_("Injected Files"))
- injected_file_content_bytes = forms.IntegerField(min_value=-1,
- label=ifcb_label)
- volumes = forms.IntegerField(min_value=-1, label=_("Volumes"))
- snapshots = forms.IntegerField(min_value=-1, label=_("Snapshots"))
- gigabytes = forms.IntegerField(min_value=-1, label=_("Gigabytes"))
- ram = forms.IntegerField(min_value=-1, label=_("RAM (MB)"))
- floating_ips = forms.IntegerField(min_value=-1, label=_("Floating IPs"))
- fixed_ips = forms.IntegerField(min_value=-1, label=_("Fixed IPs"))
- security_groups = forms.IntegerField(min_value=-1,
- label=_("Security Groups"))
- security_group_rules = forms.IntegerField(min_value=-1,
- label=_("Security Group Rules"))
-
- def __init__(self, request, *args, **kwargs):
- super(UpdateProjectQuotaAction, self).__init__(request,
- *args,
- **kwargs)
- disabled_quotas = get_disabled_quotas(request)
- for field in disabled_quotas:
- if field in self.fields:
- self.fields[field].required = False
- self.fields[field].widget = forms.HiddenInput()
-
- class Meta:
- name = _("Quota")
- slug = 'update_quotas'
- help_text = _("From here you can set quotas "
- "(max limits) for the project.")
-
-
-class UpdateProjectQuota(workflows.Step):
- action_class = UpdateProjectQuotaAction
- depends_on = ("project_id",)
- contributes = QUOTA_FIELDS
-
-
-class CreateProjectInfoAction(workflows.Action):
- name = forms.CharField(label=_("Name"))
- description = forms.CharField(widget=forms.widgets.Textarea(),
- label=_("Description"),
- required=False)
- enabled = forms.BooleanField(label=_("Enabled"),
- required=False,
- initial=True)
-
- class Meta:
- name = _("Project Info")
- help_text = _("From here you can create a new "
- "project to organize users.")
-
-
-class CreateProjectInfo(workflows.Step):
- action_class = CreateProjectInfoAction
- contributes = ("project_id",
- "name",
- "description",
- "enabled")
-
-
-class UpdateProjectMembersAction(workflows.Action):
- default_role = forms.CharField(required=False)
-
- def __init__(self, request, *args, **kwargs):
- super(UpdateProjectMembersAction, self).__init__(request,
- *args,
- **kwargs)
- err_msg = _('Unable to retrieve user list. Please try again later.')
- project_id = ''
- if 'project_id' in args[0]:
- project_id = args[0]['project_id']
-
- # Get the default role
- try:
- default_role = api.keystone.get_default_role(self.request)
- # Default role is necessary to add members to a project
- if default_role is None:
- default = getattr(settings,
- "OPENSTACK_KEYSTONE_DEFAULT_ROLE", None)
- msg = _('Could not find default role "%s" in Keystone') % \
- default
- raise exceptions.NotFound(msg)
- except:
- exceptions.handle(self.request,
- err_msg,
- redirect=reverse(INDEX_URL))
- self.fields['default_role'].initial = default_role.id
-
- # Get list of available users
- all_users = []
- domain_context = request.session.get('domain_context', None)
- try:
- all_users = api.keystone.user_list(request,
- domain=domain_context)
- except:
- exceptions.handle(request, err_msg)
- users_list = [(user.id, user.name) for user in all_users]
-
- # Get list of roles
- role_list = []
- try:
- role_list = api.keystone.role_list(request)
- except:
- exceptions.handle(request,
- err_msg,
- redirect=reverse(INDEX_URL))
- for role in role_list:
- field_name = "role_" + role.id
- label = _(role.name)
- self.fields[field_name] = forms.MultipleChoiceField(required=False,
- label=label)
- self.fields[field_name].choices = users_list
- self.fields[field_name].initial = []
-
- # Figure out users & roles
- if project_id:
- for user in all_users:
- try:
- roles = api.keystone.roles_for_user(self.request,
- user.id,
- project_id)
- except:
- exceptions.handle(request,
- err_msg,
- redirect=reverse(INDEX_URL))
- for role in roles:
- self.fields["role_" + role.id].initial.append(user.id)
-
- class Meta:
- name = _("Project Members")
- slug = "update_members"
-
-
-class UpdateProjectMembers(workflows.UpdateMembersStep):
- action_class = UpdateProjectMembersAction
- available_list_title = _("All Users")
- members_list_title = _("Project Members")
- no_available_text = _("No users found.")
- no_members_text = _("No users.")
-
- def contribute(self, data, context):
- if data:
- try:
- roles = api.keystone.role_list(self.workflow.request)
- except:
- exceptions.handle(self.workflow.request,
- _('Unable to retrieve user list.'))
-
- post = self.workflow.request.POST
- for role in roles:
- field = "role_" + role.id
- context[field] = post.getlist(field)
- return context
-
-
-class CreateProject(workflows.Workflow):
- slug = "create_project"
- name = _("Create Project")
- finalize_button_name = _("Create Project")
- success_message = _('Created new project "%s".')
- failure_message = _('Unable to create project "%s".')
- success_url = "horizon:admin:projects:index"
- default_steps = (CreateProjectInfo,
- UpdateProjectMembers,
- UpdateProjectQuota)
-
- def format_status_message(self, message):
- return message % self.context.get('name', 'unknown project')
-
- def handle(self, request, data):
- # create the project
- domain_context = self.request.session.get('domain_context', None)
- try:
- desc = data['description']
- self.object = api.keystone.tenant_create(request,
- name=data['name'],
- description=desc,
- enabled=data['enabled'],
- domain=domain_context)
- except:
- exceptions.handle(request, ignore=True)
- return False
-
- project_id = self.object.id
-
- # update project members
- users_to_add = 0
- try:
- available_roles = api.keystone.role_list(request)
-
- # count how many users are to be added
- for role in available_roles:
- role_list = data["role_" + role.id]
- users_to_add += len(role_list)
- # add new users to project
- for role in available_roles:
- role_list = data["role_" + role.id]
- users_added = 0
- for user in role_list:
- api.keystone.add_tenant_user_role(request,
- project=project_id,
- user=user,
- role=role.id)
- users_added += 1
- users_to_add -= users_added
- except:
- exceptions.handle(request, _('Failed to add %s project members '
- 'and set project quotas.'
- % users_to_add))
-
- # Update the project quota.
- nova_data = dict([(key, data[key]) for key in NOVA_QUOTA_FIELDS])
- try:
- nova.tenant_quota_update(request, project_id, **nova_data)
-
- if is_service_enabled(request, 'volume'):
- cinder_data = dict([(key, data[key]) for key in
- CINDER_QUOTA_FIELDS])
- cinder.tenant_quota_update(request,
- project_id,
- **cinder_data)
- except:
- exceptions.handle(request, _('Unable to set project quotas.'))
- return True
-
-
-class UpdateProjectInfoAction(CreateProjectInfoAction):
- enabled = forms.BooleanField(required=False, label=_("Enabled"))
-
- class Meta:
- name = _("Project Info")
- slug = 'update_info'
- help_text = _("From here you can edit the project details.")
-
-
-class UpdateProjectInfo(workflows.Step):
- action_class = UpdateProjectInfoAction
- depends_on = ("project_id",)
- contributes = ("name",
- "description",
- "enabled")
-
-
-class UpdateProject(workflows.Workflow):
- slug = "update_project"
- name = _("Edit Project")
- finalize_button_name = _("Save")
- success_message = _('Modified project "%s".')
- failure_message = _('Unable to modify project "%s".')
- success_url = "horizon:admin:projects:index"
- default_steps = (UpdateProjectInfo,
- UpdateProjectMembers,
- UpdateProjectQuota)
-
- def format_status_message(self, message):
- return message % self.context.get('name', 'unknown project')
-
- def handle(self, request, data):
- # FIXME(gabriel): This should be refactored to use Python's built-in
- # sets and do this all in a single "roles to add" and "roles to remove"
- # pass instead of the multi-pass thing happening now.
-
- project_id = data['project_id']
- # update project info
- try:
- api.keystone.tenant_update(request,
- project_id,
- name=data['name'],
- description=data['description'],
- enabled=data['enabled'])
- except:
- exceptions.handle(request, ignore=True)
- return False
-
- # update project members
- users_to_modify = 0
- try:
- # Get our role options
- available_roles = api.keystone.role_list(request)
-
- # Get the users currently associated with this project so we
- # can diff against it.
- project_members = api.keystone.user_list(request,
- project=project_id)
- users_to_modify = len(project_members)
-
- for user in project_members:
- # Check if there have been any changes in the roles of
- # Existing project members.
- current_roles = api.keystone.roles_for_user(self.request,
- user.id,
- project_id)
- current_role_ids = [role.id for role in current_roles]
- for role in available_roles:
- # Check if the user is in the list of users with this role.
- if user.id in data["role_" + role.id]:
- # Add it if necessary
- if role.id not in current_role_ids:
- # user role has changed
- api.keystone.add_tenant_user_role(
- request,
- project=project_id,
- user=user.id,
- role=role.id)
- else:
- # User role is unchanged, so remove it from the
- # remaining roles list to avoid removing it later.
- index = current_role_ids.index(role.id)
- current_role_ids.pop(index)
-
- # Prevent admins from doing stupid things to themselves.
- is_current_user = user.id == request.user.id
- is_current_project = project_id == request.user.tenant_id
- admin_roles = [role for role in current_roles
- if role.name.lower() == 'admin']
- if len(admin_roles):
- removing_admin = any([role.id in current_role_ids
- for role in admin_roles])
- else:
- removing_admin = False
- if is_current_user and is_current_project and removing_admin:
- # Cannot remove "admin" role on current(admin) project
- msg = _('You cannot revoke your administrative privileges '
- 'from the project you are currently logged into. '
- 'Please switch to another project with '
- 'administrative privileges or remove the '
- 'administrative role manually via the CLI.')
- messages.warning(request, msg)
-
- # Otherwise go through and revoke any removed roles.
- else:
- for id_to_delete in current_role_ids:
- api.keystone.remove_tenant_user_role(
- request,
- project=project_id,
- user=user.id,
- role=id_to_delete)
- users_to_modify -= 1
-
- # Grant new roles on the project.
- for role in available_roles:
- # Count how many users may be added for exception handling.
- users_to_modify += len(data["role_" + role.id])
- for role in available_roles:
- users_added = 0
- for user_id in data["role_" + role.id]:
- if not filter(lambda x: user_id == x.id, project_members):
- api.keystone.add_tenant_user_role(request,
- project=project_id,
- user=user_id,
- role=role.id)
- users_added += 1
- users_to_modify -= users_added
- except:
- exceptions.handle(request, _('Failed to modify %s project members '
- 'and update project quotas.'
- % users_to_modify))
- return True
-
- # update the project quota
- nova_data = dict([(key, data[key]) for key in NOVA_QUOTA_FIELDS])
- try:
- nova.tenant_quota_update(request,
- project_id,
- **nova_data)
-
- if is_service_enabled(request, 'volume'):
- cinder_data = dict([(key, data[key]) for key in
- CINDER_QUOTA_FIELDS])
- cinder.tenant_quota_update(request,
- project_id,
- **cinder_data)
- return True
- except:
- exceptions.handle(request, _('Modified project information and '
- 'members, but unable to modify '
- 'project quotas.'))
- return True
diff --git a/openstack_dashboard/dashboards/admin/roles/__init__.py b/openstack_dashboard/dashboards/admin/roles/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/roles/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/roles/forms.py b/openstack_dashboard/dashboards/admin/roles/forms.py
deleted file mode 100644
index 03ad1f06..00000000
--- a/openstack_dashboard/dashboards/admin/roles/forms.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-class CreateRoleForm(forms.SelfHandlingForm):
- name = forms.CharField(label=_("Role Name"))
-
- def handle(self, request, data):
- try:
- new_user = api.keystone.role_create(request, data["name"])
- messages.success(request, _("Role created successfully."))
- return new_user
- except:
- exceptions.handle(request, _('Unable to create role.'))
-
-
-class UpdateRoleForm(forms.SelfHandlingForm):
- id = forms.CharField(label=_("ID"), widget=forms.HiddenInput)
- name = forms.CharField(label=_("Role Name"))
-
- def handle(self, request, data):
- try:
- api.keystone.role_update(request, data['id'], data["name"])
- messages.success(request, _("Role updated successfully."))
- return True
- except:
- exceptions.handle(request, _('Unable to update role.'))
diff --git a/openstack_dashboard/dashboards/admin/roles/panel.py b/openstack_dashboard/dashboards/admin/roles/panel.py
deleted file mode 100644
index f8fa6748..00000000
--- a/openstack_dashboard/dashboards/admin/roles/panel.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.api.keystone import VERSIONS as IDENTITY_VERSIONS
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Roles(horizon.Panel):
- name = _("Roles")
- slug = 'roles'
-
-if IDENTITY_VERSIONS.active >= 3:
- dashboard.Admin.register(Roles)
diff --git a/openstack_dashboard/dashboards/admin/roles/tables.py b/openstack_dashboard/dashboards/admin/roles/tables.py
deleted file mode 100644
index 97431e18..00000000
--- a/openstack_dashboard/dashboards/admin/roles/tables.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Hewlett-Packard Development Company, L.P.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateRoleLink(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Role")
- url = "horizon:admin:roles:create"
- classes = ("ajax-modal", "btn-create")
-
- def allowed(self, request, role):
- return api.keystone.keystone_can_edit_role()
-
-
-class EditRoleLink(tables.LinkAction):
- name = "edit"
- verbose_name = _("Edit")
- url = "horizon:admin:roles:update"
- classes = ("ajax-modal", "btn-edit")
-
- def allowed(self, request, role):
- return api.keystone.keystone_can_edit_role()
-
-
-class DeleteRolesAction(tables.DeleteAction):
- data_type_singular = _("Role")
- data_type_plural = _("Roles")
-
- def allowed(self, request, role):
- return api.keystone.keystone_can_edit_role()
-
- def delete(self, request, obj_id):
- api.keystone.role_delete(request, obj_id)
-
-
-class RoleFilterAction(tables.FilterAction):
- def filter(self, table, roles, filter_string):
- """ Naive case-insensitive search """
- q = filter_string.lower()
- return [role for role in roles
- if q in role.name.lower()]
-
-
-class RolesTable(tables.DataTable):
- name = tables.Column('name', verbose_name=_('Role Name'))
- id = tables.Column('id', verbose_name=_('Role ID'))
-
- class Meta:
- name = "roles"
- verbose_name = _("Roles")
- row_actions = (EditRoleLink, DeleteRolesAction)
- table_actions = (RoleFilterAction, CreateRoleLink, DeleteRolesAction)
diff --git a/openstack_dashboard/dashboards/admin/roles/templates/roles/_create.html b/openstack_dashboard/dashboards/admin/roles/templates/roles/_create.html
deleted file mode 100644
index 4ddd8bc7..00000000
--- a/openstack_dashboard/dashboards/admin/roles/templates/roles/_create.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_role_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:roles:create' %}{% endblock %}
-
-{% block modal-header %}{% trans "Create Role" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can create a new role." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Role" %}" />
- <a href="{% url 'horizon:admin:roles:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/roles/templates/roles/_update.html b/openstack_dashboard/dashboards/admin/roles/templates/roles/_update.html
deleted file mode 100644
index 6b3c4c42..00000000
--- a/openstack_dashboard/dashboards/admin/roles/templates/roles/_update.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_role_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:roles:update' role.id %}{% endblock %}
-
-{% block modal-header %}{% trans "Update Role" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can edit the role's details." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Update Role" %}" />
- <a href="{% url 'horizon:admin:roles:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/roles/templates/roles/create.html b/openstack_dashboard/dashboards/admin/roles/templates/roles/create.html
deleted file mode 100644
index 42835afe..00000000
--- a/openstack_dashboard/dashboards/admin/roles/templates/roles/create.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Role" %}{% endblock %}
-
-{% block page_header %}
- {# to make searchable false, just remove it from the include statement #}
- {% include "horizon/common/_page_header.html" with title=_("Create Role") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/roles/_create.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/roles/templates/roles/index.html b/openstack_dashboard/dashboards/admin/roles/templates/roles/index.html
deleted file mode 100644
index 6a61c979..00000000
--- a/openstack_dashboard/dashboards/admin/roles/templates/roles/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Roles" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Roles") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/roles/templates/roles/update.html b/openstack_dashboard/dashboards/admin/roles/templates/roles/update.html
deleted file mode 100644
index 233d54cd..00000000
--- a/openstack_dashboard/dashboards/admin/roles/templates/roles/update.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Update Role" %}{% endblock %}
-
-{% block page_header %}
- {# to make searchable false, just remove it from the include statement #}
- {% include "horizon/common/_page_header.html" with title=_("Update Role") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/roles/_update.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/roles/tests.py b/openstack_dashboard/dashboards/admin/roles/tests.py
deleted file mode 100644
index 4fa9127e..00000000
--- a/openstack_dashboard/dashboards/admin/roles/tests.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IgnoreArg
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-ROLES_INDEX_URL = reverse('horizon:admin:roles:index')
-ROLES_CREATE_URL = reverse('horizon:admin:roles:create')
-ROLES_UPDATE_URL = reverse('horizon:admin:roles:update', args=[1])
-
-
-class RolesViewTests(test.BaseAdminViewTests):
- @test.create_stubs({api.keystone: ('role_list',)})
- def test_index(self):
- api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
-
- self.mox.ReplayAll()
-
- res = self.client.get(ROLES_INDEX_URL)
- self.assertContains(res, 'Create Role')
- self.assertContains(res, 'Edit')
- self.assertContains(res, 'Delete Role')
-
- self.assertTemplateUsed(res, 'admin/roles/index.html')
- self.assertItemsEqual(res.context['table'].data, self.roles.list())
-
- @test.create_stubs({api.keystone: ('role_list',
- 'keystone_can_edit_role', )})
- def test_index_with_keystone_can_edit_role_false(self):
- api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
- api.keystone.keystone_can_edit_role() \
- .MultipleTimes().AndReturn(False)
- self.mox.ReplayAll()
-
- res = self.client.get(ROLES_INDEX_URL)
-
- self.assertNotContains(res, 'Create Role')
- self.assertNotContains(res, 'Edit')
- self.assertNotContains(res, 'Delete Role')
-
- self.assertTemplateUsed(res, 'admin/roles/index.html')
- self.assertItemsEqual(res.context['table'].data, self.roles.list())
-
- @test.create_stubs({api.keystone: ('role_create', )})
- def test_create(self):
- role = self.roles.first()
-
- api.keystone.role_create(IgnoreArg(), role.name).AndReturn(role)
-
- self.mox.ReplayAll()
-
- formData = {'method': 'CreateRoleForm', 'name': role.name}
- res = self.client.post(ROLES_CREATE_URL, formData)
-
- self.assertNoFormErrors(res)
- self.assertMessageCount(success=1)
-
- @test.create_stubs({api.keystone: ('role_get', 'role_update')})
- def test_update(self):
- role = self.roles.first()
- new_role_name = 'test_name'
-
- api.keystone.role_get(IsA(http.HttpRequest), role.id).AndReturn(role)
- api.keystone.role_update(IsA(http.HttpRequest),
- role.id,
- new_role_name).AndReturn(None)
-
- self.mox.ReplayAll()
-
- formData = {'method': 'UpdateRoleForm',
- 'id': role.id,
- 'name': new_role_name}
-
- res = self.client.post(ROLES_UPDATE_URL, formData)
-
- self.assertNoFormErrors(res)
- self.assertMessageCount(success=1)
-
- @test.create_stubs({api.keystone: ('role_list', 'role_delete')})
- def test_delete(self):
- role = self.roles.first()
-
- api.keystone.role_list(IsA(http.HttpRequest)) \
- .AndReturn(self.roles.list())
- api.keystone.role_delete(IsA(http.HttpRequest),
- role.id).AndReturn(None)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'roles__delete__%s' % role.id}
- res = self.client.post(ROLES_INDEX_URL, formData)
-
- self.assertNoFormErrors(res)
diff --git a/openstack_dashboard/dashboards/admin/roles/urls.py b/openstack_dashboard/dashboards/admin/roles/urls.py
deleted file mode 100644
index 178888a1..00000000
--- a/openstack_dashboard/dashboards/admin/roles/urls.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.roles.views import CreateView
-from openstack_dashboard.dashboards.admin.roles.views import IndexView
-from openstack_dashboard.dashboards.admin.roles.views import UpdateView
-
-urlpatterns = patterns('openstack_dashboard.dashboards.admin.roles.views',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^(?P<role_id>[^/]+)/update/$', UpdateView.as_view(), name='update'),
- url(r'^create/$', CreateView.as_view(), name='create'))
diff --git a/openstack_dashboard/dashboards/admin/roles/views.py b/openstack_dashboard/dashboards/admin/roles/views.py
deleted file mode 100644
index 87c7d46c..00000000
--- a/openstack_dashboard/dashboards/admin/roles/views.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 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.
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.admin.roles.forms import CreateRoleForm
-from openstack_dashboard.dashboards.admin.roles.forms import UpdateRoleForm
-from openstack_dashboard.dashboards.admin.roles.tables import RolesTable
-
-
-class IndexView(tables.DataTableView):
- table_class = RolesTable
- template_name = 'admin/roles/index.html'
-
- def get_data(self):
- roles = []
- try:
- roles = api.keystone.role_list(self.request)
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve roles list.'))
- return roles
-
-
-class UpdateView(forms.ModalFormView):
- form_class = UpdateRoleForm
- template_name = 'admin/roles/update.html'
- success_url = reverse_lazy('horizon:admin:roles:index')
-
- def get_object(self):
- if not hasattr(self, "_object"):
- try:
- self._object = api.keystone.role_get(self.request,
- self.kwargs['role_id'])
- except:
- redirect = reverse("horizon:admin:roles:index")
- exceptions.handle(self.request,
- _('Unable to update role.'),
- redirect=redirect)
- return self._object
-
- def get_context_data(self, **kwargs):
- context = super(UpdateView, self).get_context_data(**kwargs)
- context['role'] = self.get_object()
- return context
-
- def get_initial(self):
- role = self.get_object()
- return {'id': role.id,
- 'name': role.name}
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateRoleForm
- template_name = 'admin/roles/create.html'
- success_url = reverse_lazy('horizon:admin:roles:index')
diff --git a/openstack_dashboard/dashboards/admin/routers/__init__.py b/openstack_dashboard/dashboards/admin/routers/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/routers/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/routers/panel.py b/openstack_dashboard/dashboards/admin/routers/panel.py
deleted file mode 100644
index 69709363..00000000
--- a/openstack_dashboard/dashboards/admin/routers/panel.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Routers(horizon.Panel):
- name = _("Routers")
- slug = 'routers'
- permissions = ('openstack.services.network',)
-
-dashboard.Admin.register(Routers)
diff --git a/openstack_dashboard/dashboards/admin/routers/ports/__init__.py b/openstack_dashboard/dashboards/admin/routers/ports/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/routers/ports/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/routers/ports/tables.py b/openstack_dashboard/dashboards/admin/routers/ports/tables.py
deleted file mode 100644
index 83b6be24..00000000
--- a/openstack_dashboard/dashboards/admin/routers/ports/tables.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-from openstack_dashboard.dashboards.project.networks.ports.tables import\
- get_fixed_ips
-from openstack_dashboard.dashboards.project.routers.ports.tables import\
- get_device_owner
-
-
-LOG = logging.getLogger(__name__)
-
-
-class PortsTable(tables.DataTable):
- name = tables.Column("name",
- verbose_name=_("Name"),
- link="horizon:admin:networks:ports:detail")
- fixed_ips = tables.Column(get_fixed_ips, verbose_name=_("Fixed IPs"))
- status = tables.Column("status", verbose_name=_("Status"))
- device_owner = tables.Column(get_device_owner,
- verbose_name=_("Type"))
- admin_state = tables.Column("admin_state",
- verbose_name=_("Admin State"))
-
- def get_object_display(self, port):
- return port.id
-
- class Meta:
- name = "interfaces"
- verbose_name = _("Interfaces")
diff --git a/openstack_dashboard/dashboards/admin/routers/ports/tabs.py b/openstack_dashboard/dashboards/admin/routers/ports/tabs.py
deleted file mode 100644
index 16d63b85..00000000
--- a/openstack_dashboard/dashboards/admin/routers/ports/tabs.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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 logging
-
-from horizon import tabs
-from openstack_dashboard.dashboards.project.routers.ports import tabs as r_tabs
-
-LOG = logging.getLogger(__name__)
-
-
-class OverviewTab(r_tabs.OverviewTab):
- template_name = "admin/networks/ports/_detail_overview.html"
- failure_url = "horizon:admin:routers:index"
-
-
-class PortDetailTabs(tabs.TabGroup):
- slug = "port_details"
- tabs = (OverviewTab,)
diff --git a/openstack_dashboard/dashboards/admin/routers/ports/urls.py b/openstack_dashboard/dashboards/admin/routers/ports/urls.py
deleted file mode 100644
index 89ac65f8..00000000
--- a/openstack_dashboard/dashboards/admin/routers/ports/urls.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NTT MCL
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.routers.ports.views import DetailView
-
-PORTS = r'^(?P<port_id>[^/]+)/%s$'
-
-urlpatterns = patterns('horizon.dashboards.admin.networks.ports.views',
- url(PORTS % 'detail', DetailView.as_view(), name='detail'))
diff --git a/openstack_dashboard/dashboards/admin/routers/ports/views.py b/openstack_dashboard/dashboards/admin/routers/ports/views.py
deleted file mode 100644
index 06deaf44..00000000
--- a/openstack_dashboard/dashboards/admin/routers/ports/views.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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 logging
-
-from horizon import tabs
-
-from openstack_dashboard.dashboards.admin.routers.ports.tabs \
- import PortDetailTabs
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DetailView(tabs.TabView):
- tab_group_class = PortDetailTabs
- template_name = 'admin/networks/ports/detail.html'
diff --git a/openstack_dashboard/dashboards/admin/routers/tables.py b/openstack_dashboard/dashboards/admin/routers/tables.py
deleted file mode 100644
index a9d262e9..00000000
--- a/openstack_dashboard/dashboards/admin/routers/tables.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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 logging
-
-from django.template.defaultfilters import title
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.routers import tables as r_tables
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DeleteRouter(r_tables.DeleteRouter):
- redirect_url = "horizon:admin:routers:index"
-
- def delete(self, request, obj_id):
- search_opts = {'device_owner': 'network:router_interface',
- 'device_id': obj_id}
- ports = api.neutron.port_list(request, **search_opts)
- for port in ports:
- api.neutron.router_remove_interface(request, obj_id,
- port_id=port.id)
- super(DeleteRouter, self).delete(request, obj_id)
-
- def allowed(self, request, router=None):
- return True
-
-
-class UpdateRow(tables.Row):
- ajax = True
-
- def get_data(self, request, router_id):
- router = api.neutron.router_get(request, router_id)
- return router
-
-
-class RoutersTable(tables.DataTable):
- tenant = tables.Column("tenant_name", verbose_name=_("Project"))
- name = tables.Column("name",
- verbose_name=_("Name"),
- link="horizon:admin:routers:detail")
- status = tables.Column("status",
- filters=(title,),
- verbose_name=_("Status"),
- status=True)
- ext_net = tables.Column(r_tables.get_external_network,
- verbose_name=_("External Network"))
-
- def get_object_display(self, obj):
- return obj.name
-
- class Meta:
- name = "Routers"
- verbose_name = _("Routers")
- status_columns = ["status"]
- row_class = UpdateRow
- table_actions = (DeleteRouter,)
- row_actions = (DeleteRouter,)
diff --git a/openstack_dashboard/dashboards/admin/routers/tabs.py b/openstack_dashboard/dashboards/admin/routers/tabs.py
deleted file mode 100644
index 4fe386f2..00000000
--- a/openstack_dashboard/dashboards/admin/routers/tabs.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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 horizon import tabs
-from openstack_dashboard.dashboards.project.routers import tabs as r_tabs
-
-
-class OverviewTab(r_tabs.OverviewTab):
- template_name = ("admin/routers/_detail_overview.html")
- redirect_url = 'horizon:admin:routers:index'
-
-
-class RouterDetailTabs(tabs.TabGroup):
- slug = "router_details"
- tabs = (OverviewTab,)
diff --git a/openstack_dashboard/dashboards/admin/routers/templates/routers/_detail_overview.html b/openstack_dashboard/dashboards/admin/routers/templates/routers/_detail_overview.html
deleted file mode 100644
index db0dc929..00000000
--- a/openstack_dashboard/dashboards/admin/routers/templates/routers/_detail_overview.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% load i18n sizeformat parse_date %}
-
-<h3>{% trans "Router Overview" %}: {{router.name }}</h3>
-
-<div class="info detail">
- <dl>
- <dt>{% trans "Name" %}</dt>
- <dd>{{ router.name|default:_("None") }}</dd>
- <dt>{% trans "ID" %}</dt>
- <dd>{{ router.id }}</dd>
- <dt>{% trans "Project ID" %}</dt>
- <dd>{{ router.tenant_id }}</dd>
- <dt>{% trans "Status" %}</dt>
- <dd>{{ router.status|capfirst }}</dd>
- {% if router.external_gateway_info %}
- <dt>{% trans "External Gateway Information" %}</dt>
- <dd>{% trans "Connected External Network" %}:
- {{ router.external_gateway_info.network }}</dd>
- {% endif %}
- </dl>
-</div>
-
diff --git a/openstack_dashboard/dashboards/admin/routers/templates/routers/detail.html b/openstack_dashboard/dashboards/admin/routers/templates/routers/detail.html
deleted file mode 100644
index 15c46bce..00000000
--- a/openstack_dashboard/dashboards/admin/routers/templates/routers/detail.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Router Details" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Router Detail") %}
-{% endblock page_header %}
-
-{% block main %}
-{% include "admin/routers/_detail_overview.html" %}
-<hr>
-<div id="interfaces">
- {{ interfaces_table.render }}
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/routers/templates/routers/index.html b/openstack_dashboard/dashboards/admin/routers/templates/routers/index.html
deleted file mode 100644
index 8389f15a..00000000
--- a/openstack_dashboard/dashboards/admin/routers/templates/routers/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Routers" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Routers") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/routers/tests.py b/openstack_dashboard/dashboards/admin/routers/tests.py
deleted file mode 100644
index 41ec2d1f..00000000
--- a/openstack_dashboard/dashboards/admin/routers/tests.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.routers import tests as r_test
-from openstack_dashboard.test import helpers as test
-
-
-class RouterTests(test.BaseAdminViewTests, r_test.RouterTests):
- DASHBOARD = 'admin'
- INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD)
- DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD
-
- @test.create_stubs({api.neutron: ('router_list', 'network_list'),
- api.keystone: ('tenant_list',)})
- def test_index(self):
- tenants = self.tenants.list()
- api.neutron.router_list(
- IsA(http.HttpRequest),
- search_opts=None).AndReturn(self.routers.list())
- api.keystone.tenant_list(IsA(http.HttpRequest))\
- .AndReturn([tenants, False])
- self._mock_external_network_list()
-
- self.mox.ReplayAll()
-
- res = self.client.get(self.INDEX_URL)
-
- self.assertTemplateUsed(res, '%s/routers/index.html' % self.DASHBOARD)
- routers = res.context['table'].data
- self.assertItemsEqual(routers, self.routers.list())
-
- @test.create_stubs({api.neutron: ('router_list',),
- api.keystone: ('tenant_list',)})
- def test_index_router_list_exception(self):
- api.neutron.router_list(
- IsA(http.HttpRequest),
- search_opts=None).AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- res = self.client.get(self.INDEX_URL)
-
- self.assertTemplateUsed(res, '%s/routers/index.html' % self.DASHBOARD)
- self.assertEqual(len(res.context['table'].data), 0)
- self.assertMessageCount(res, error=1)
diff --git a/openstack_dashboard/dashboards/admin/routers/urls.py b/openstack_dashboard/dashboards/admin/routers/urls.py
deleted file mode 100644
index 21f8b156..00000000
--- a/openstack_dashboard/dashboards/admin/routers/urls.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.routers.views import DetailView
-from openstack_dashboard.dashboards.admin.routers.views import IndexView
-
-
-urlpatterns = patterns('horizon.dashboards.admin.routers.views',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^(?P<router_id>[^/]+)/$',
- DetailView.as_view(),
- name='detail'),
-)
diff --git a/openstack_dashboard/dashboards/admin/routers/views.py b/openstack_dashboard/dashboards/admin/routers/views.py
deleted file mode 100644
index e13d4115..00000000
--- a/openstack_dashboard/dashboards/admin/routers/views.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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.
-
-"""
-Views for managing Neutron Routers.
-"""
-
-import logging
-
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.admin.networks import views as n_views
-from openstack_dashboard.dashboards.project.routers import views as r_views
-
-from openstack_dashboard.dashboards.admin.routers.ports.tables \
- import PortsTable
-from openstack_dashboard.dashboards.admin.routers.tables import RoutersTable
-
-
-LOG = logging.getLogger(__name__)
-
-
-class IndexView(r_views.IndexView, n_views.IndexView):
- table_class = RoutersTable
- template_name = 'admin/routers/index.html'
-
- def _get_routers(self, search_opts=None):
- try:
- routers = api.neutron.router_list(self.request,
- search_opts=search_opts)
- except:
- routers = []
- exceptions.handle(self.request,
- _('Unable to retrieve router list.'))
- if routers:
- tenant_dict = self._get_tenant_list()
- ext_net_dict = self._list_external_networks()
- for r in routers:
- # Set tenant name
- tenant = tenant_dict.get(r.tenant_id, None)
- r.tenant_name = getattr(tenant, 'name', None)
- # If name is empty use UUID as name
- r.set_id_as_name_if_empty()
- # Set external network name
- self._set_external_network(r, ext_net_dict)
- return routers
-
- def get_data(self):
- routers = self._get_routers()
- return routers
-
-
-class DetailView(r_views.DetailView):
- table_classes = (PortsTable, )
- template_name = 'admin/routers/detail.html'
- failure_url = reverse_lazy('horizon:admin:routers:index')
diff --git a/openstack_dashboard/dashboards/admin/users/__init__.py b/openstack_dashboard/dashboards/admin/users/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/users/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/users/forms.py b/openstack_dashboard/dashboards/admin/users/forms.py
deleted file mode 100644
index c0039a3c..00000000
--- a/openstack_dashboard/dashboards/admin/users/forms.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.forms import ValidationError
-from django.utils.translation import ugettext_lazy as _
-from django.views.decorators.debug import sensitive_variables
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-from horizon.utils import validators
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class BaseUserForm(forms.SelfHandlingForm):
- def __init__(self, request, *args, **kwargs):
- super(BaseUserForm, self).__init__(request, *args, **kwargs)
-
- domain_context = request.session.get('domain_context', None)
- # Populate project choices
- project_choices = [('', _("Select a project"))]
-
- # If the user is already set (update action), list only projects which
- # the user has access to.
- user_id = kwargs['initial'].get('id', None)
- projects, has_more = api.keystone.tenant_list(request, user=user_id)
- if domain_context:
- domain_projects = [project for project in projects
- if project.domain_id == domain_context]
- projects = domain_projects
- for project in projects:
- if project.enabled:
- project_choices.append((project.id, project.name))
- self.fields['project'].choices = project_choices
-
- def clean(self):
- '''Check to make sure password fields match.'''
- data = super(forms.Form, self).clean()
- if 'password' in data:
- if data['password'] != data.get('confirm_password', None):
- raise ValidationError(_('Passwords do not match.'))
- return data
-
-
-ADD_PROJECT_URL = "horizon:admin:projects:create"
-
-
-class CreateUserForm(BaseUserForm):
- name = forms.CharField(label=_("User Name"))
- email = forms.EmailField(
- label=_("Email"),
- required=False)
- password = forms.RegexField(
- label=_("Password"),
- widget=forms.PasswordInput(render_value=False),
- regex=validators.password_validator(),
- error_messages={'invalid': validators.password_validator_msg()})
- confirm_password = forms.CharField(
- label=_("Confirm Password"),
- required=False,
- widget=forms.PasswordInput(render_value=False))
- project = forms.DynamicChoiceField(label=_("Primary Project"),
- add_item_link=ADD_PROJECT_URL)
- role_id = forms.ChoiceField(label=_("Role"))
-
- def __init__(self, *args, **kwargs):
- roles = kwargs.pop('roles')
- super(CreateUserForm, self).__init__(*args, **kwargs)
- role_choices = [(role.id, role.name) for role in roles]
- self.fields['role_id'].choices = role_choices
-
- # We have to protect the entire "data" dict because it contains the
- # password and confirm_password strings.
- @sensitive_variables('data')
- def handle(self, request, data):
- domain_context = request.session.get('domain_context', None)
- try:
- LOG.info('Creating user with name "%s"' % data['name'])
- new_user = api.keystone.user_create(request,
- name=data['name'],
- email=data['email'],
- password=data['password'],
- project=data['project'],
- enabled=True,
- domain=domain_context)
- messages.success(request,
- _('User "%s" was successfully created.')
- % data['name'])
- if data['role_id']:
- try:
- api.keystone.add_tenant_user_role(request,
- data['project'],
- new_user.id,
- data['role_id'])
- except:
- exceptions.handle(request,
- _('Unable to add user '
- 'to primary project.'))
- return new_user
- except:
- exceptions.handle(request, _('Unable to create user.'))
-
-
-class UpdateUserForm(BaseUserForm):
- id = forms.CharField(label=_("ID"), widget=forms.HiddenInput)
- name = forms.CharField(label=_("User Name"))
- email = forms.EmailField(
- label=_("Email"),
- required=False)
- password = forms.RegexField(
- label=_("Password"),
- widget=forms.PasswordInput(render_value=False),
- regex=validators.password_validator(),
- required=False,
- error_messages={'invalid': validators.password_validator_msg()})
- confirm_password = forms.CharField(
- label=_("Confirm Password"),
- widget=forms.PasswordInput(render_value=False),
- required=False)
- project = forms.ChoiceField(label=_("Primary Project"))
-
- def __init__(self, request, *args, **kwargs):
- super(UpdateUserForm, self).__init__(request, *args, **kwargs)
-
- if api.keystone.keystone_can_edit_user() is False:
- for field in ('name', 'email', 'password', 'confirm_password'):
- self.fields.pop(field)
-
- # We have to protect the entire "data" dict because it contains the
- # password and confirm_password strings.
- @sensitive_variables('data', 'password')
- def handle(self, request, data):
- user = data.pop('id')
-
- # Throw away the password confirmation, we're done with it.
- data.pop('confirm_password', None)
-
- try:
- api.keystone.user_update(request, user, **data)
- messages.success(request,
- _('User has been updated successfully.'))
- except:
- exceptions.handle(request, ignore=True)
- messages.error(request, _('Unable to update the user.'))
- return True
diff --git a/openstack_dashboard/dashboards/admin/users/panel.py b/openstack_dashboard/dashboards/admin/users/panel.py
deleted file mode 100644
index a813fa4a..00000000
--- a/openstack_dashboard/dashboards/admin/users/panel.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Users(horizon.Panel):
- name = _("Users")
- slug = 'users'
-
-
-dashboard.Admin.register(Users)
diff --git a/openstack_dashboard/dashboards/admin/users/tables.py b/openstack_dashboard/dashboards/admin/users/tables.py
deleted file mode 100644
index 9e30cc29..00000000
--- a/openstack_dashboard/dashboards/admin/users/tables.py
+++ /dev/null
@@ -1,122 +0,0 @@
-import logging
-
-from django.template import defaultfilters
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import messages
-from horizon import tables
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-ENABLE = 0
-DISABLE = 1
-
-
-class CreateUserLink(tables.LinkAction):
- name = "create"
- verbose_name = _("Create User")
- url = "horizon:admin:users:create"
- classes = ("ajax-modal", "btn-create")
-
- def allowed(self, request, user):
- return api.keystone.keystone_can_edit_user()
-
-
-class EditUserLink(tables.LinkAction):
- name = "edit"
- verbose_name = _("Edit")
- url = "horizon:admin:users:update"
- classes = ("ajax-modal", "btn-edit")
-
- def allowed(self, request, user):
- return api.keystone.keystone_can_edit_user()
-
-
-class ToggleEnabled(tables.BatchAction):
- name = "toggle"
- action_present = (_("Enable"), _("Disable"))
- action_past = (_("Enabled"), _("Disabled"))
- data_type_singular = _("User")
- data_type_plural = _("Users")
- classes = ("btn-toggle",)
-
- def allowed(self, request, user=None):
- if not api.keystone.keystone_can_edit_user():
- return False
-
- self.enabled = True
- if not user:
- return self.enabled
- self.enabled = user.enabled
- if self.enabled:
- self.current_present_action = DISABLE
- else:
- self.current_present_action = ENABLE
- return True
-
- def update(self, request, user=None):
- super(ToggleEnabled, self).update(request, user)
- if user and user.id == request.user.id:
- self.attrs["disabled"] = "disabled"
-
- def action(self, request, obj_id):
- if obj_id == request.user.id:
- messages.info(request, _('You cannot disable the user you are '
- 'currently logged in as.'))
- return
- if self.enabled:
- api.keystone.user_update_enabled(request, obj_id, False)
- self.current_past_action = DISABLE
- else:
- api.keystone.user_update_enabled(request, obj_id, True)
- self.current_past_action = ENABLE
-
-
-class DeleteUsersAction(tables.DeleteAction):
- data_type_singular = _("User")
- data_type_plural = _("Users")
-
- def allowed(self, request, datum):
- if not api.keystone.keystone_can_edit_user() or \
- (datum and datum.id == request.user.id):
- return False
- return True
-
- def delete(self, request, obj_id):
- api.keystone.user_delete(request, obj_id)
-
-
-class UserFilterAction(tables.FilterAction):
- def filter(self, table, users, filter_string):
- """ Naive case-insensitive search """
- q = filter_string.lower()
- return [user for user in users
- if q in user.name.lower()
- or q in user.email.lower()]
-
-
-class UsersTable(tables.DataTable):
- STATUS_CHOICES = (
- ("true", True),
- ("false", False)
- )
- name = tables.Column('name', verbose_name=_('User Name'))
- email = tables.Column('email', verbose_name=_('Email'),
- filters=[defaultfilters.urlize])
- # Default tenant is not returned from Keystone currently.
- #default_tenant = tables.Column('default_tenant',
- # verbose_name=_('Default Project'))
- id = tables.Column('id', verbose_name=_('User ID'))
- enabled = tables.Column('enabled', verbose_name=_('Enabled'),
- status=True,
- status_choices=STATUS_CHOICES,
- empty_value="False")
-
- class Meta:
- name = "users"
- verbose_name = _("Users")
- row_actions = (EditUserLink, ToggleEnabled, DeleteUsersAction)
- table_actions = (UserFilterAction, CreateUserLink, DeleteUsersAction)
diff --git a/openstack_dashboard/dashboards/admin/users/templates/users/_create.html b/openstack_dashboard/dashboards/admin/users/templates/users/_create.html
deleted file mode 100644
index 9da7b761..00000000
--- a/openstack_dashboard/dashboards/admin/users/templates/users/_create.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_user_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:users:create' %}{% endblock %}
-
-{% block modal-header %}{% trans "Create User" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can create a new user and assign them to a project." %}</p>
-</div>
-
-<script type="text/javascript">
- if (typeof horizon.user !== 'undefined') {
- horizon.user.init();
- } else {
- addHorizonLoadEvent(function() {
- horizon.user.init();
- });
- }
-</script>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create User" %}" />
- <a href="{% url 'horizon:admin:users:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/users/templates/users/_update.html b/openstack_dashboard/dashboards/admin/users/templates/users/_update.html
deleted file mode 100644
index 98e9013a..00000000
--- a/openstack_dashboard/dashboards/admin/users/templates/users/_update.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_user_form{% endblock %}
-{% block form_action %}{% url 'horizon:admin:users:update' user.id %}{% endblock %}
-
-{% block modal-header %}{% trans "Update User" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can edit the user's details, including their default project." %}</p>
-</div>
-
-<script type="text/javascript">
- if (typeof horizon.user !== 'undefined') {
- horizon.user.init();
- } else {
- addHorizonLoadEvent(function() {
- horizon.user.init();
- });
- }
-</script>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Update User" %}" />
- <a href="{% url 'horizon:admin:users:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/users/templates/users/create.html b/openstack_dashboard/dashboards/admin/users/templates/users/create.html
deleted file mode 100644
index 6daa7117..00000000
--- a/openstack_dashboard/dashboards/admin/users/templates/users/create.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create User" %}{% endblock %}
-
-{% block page_header %}
- {# to make searchable false, just remove it from the include statement #}
- {% include "horizon/common/_page_header.html" with title=_("Create User") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/users/_create.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/users/templates/users/index.html b/openstack_dashboard/dashboards/admin/users/templates/users/index.html
deleted file mode 100644
index 53c327d8..00000000
--- a/openstack_dashboard/dashboards/admin/users/templates/users/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Users" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_domain_page_header.html" with title=_("Users") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/users/templates/users/update.html b/openstack_dashboard/dashboards/admin/users/templates/users/update.html
deleted file mode 100644
index e9bac52a..00000000
--- a/openstack_dashboard/dashboards/admin/users/templates/users/update.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Update User" %}{% endblock %}
-
-{% block page_header %}
- {# to make searchable false, just remove it from the include statement #}
- {% include "horizon/common/_page_header.html" with title=_("Update User") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/users/_update.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/users/tests.py b/openstack_dashboard/dashboards/admin/users/tests.py
deleted file mode 100644
index 276fdbfc..00000000
--- a/openstack_dashboard/dashboards/admin/users/tests.py
+++ /dev/null
@@ -1,462 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from socket import timeout as socket_timeout
-
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IgnoreArg
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-USERS_INDEX_URL = reverse('horizon:admin:users:index')
-USER_CREATE_URL = reverse('horizon:admin:users:create')
-USER_UPDATE_URL = reverse('horizon:admin:users:update', args=[1])
-
-
-class UsersViewTests(test.BaseAdminViewTests):
- def _get_domain_id(self):
- return self.request.session.get('domain_context', None)
-
- def _get_users(self, domain_id):
- if not domain_id:
- users = self.users.list()
- else:
- users = [user for user in self.users.list()
- if user.domain_id == domain_id]
- return users
-
- @test.create_stubs({api.keystone: ('user_list',)})
- def test_index(self):
- domain_id = self._get_domain_id()
- users = self._get_users(domain_id)
- api.keystone.user_list(IgnoreArg(), domain=domain_id) \
- .AndReturn(users)
-
- self.mox.ReplayAll()
-
- res = self.client.get(USERS_INDEX_URL)
-
- self.assertTemplateUsed(res, 'admin/users/index.html')
- self.assertItemsEqual(res.context['table'].data, users)
-
- if domain_id:
- for user in res.context['table'].data:
- self.assertItemsEqual(user.domain_id, domain_id)
-
- def test_index_with_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_index()
-
- @test.create_stubs({api.keystone: ('user_create',
- 'tenant_list',
- 'add_tenant_user_role',
- 'get_default_role',
- 'role_list')})
- def test_create(self):
- user = self.users.get(id="1")
- domain_id = self._get_domain_id()
-
- role = self.roles.first()
-
- api.keystone.tenant_list(IgnoreArg(), user=None) \
- .AndReturn([self.tenants.list(), False])
- api.keystone.user_create(IgnoreArg(),
- name=user.name,
- email=user.email,
- password=user.password,
- project=self.tenant.id,
- enabled=True,
- domain=domain_id).AndReturn(user)
- api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
- api.keystone.get_default_role(IgnoreArg()).AndReturn(role)
- api.keystone.add_tenant_user_role(IgnoreArg(), self.tenant.id,
- user.id, role.id)
-
- self.mox.ReplayAll()
-
- formData = {'method': 'CreateUserForm',
- 'name': user.name,
- 'email': user.email,
- 'password': user.password,
- 'project': self.tenant.id,
- 'role_id': self.roles.first().id,
- 'confirm_password': user.password}
- res = self.client.post(USER_CREATE_URL, formData)
-
- self.assertNoFormErrors(res)
- self.assertMessageCount(success=1)
-
- def test_create_with_domain(self):
- domain = self.domains.get(id="1")
- self.setSessionValues(domain_context=domain.id,
- domain_context_name=domain.name)
- self.test_create()
-
- @test.create_stubs({api.keystone: ('tenant_list',
- 'role_list',
- 'get_default_role')})
- def test_create_with_password_mismatch(self):
- user = self.users.get(id="1")
-
- api.keystone.tenant_list(IgnoreArg(), user=None) \
- .AndReturn([self.tenants.list(), False])
- api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
- api.keystone.get_default_role(IgnoreArg()) \
- .AndReturn(self.roles.first())
-
- self.mox.ReplayAll()
-
- formData = {'method': 'CreateUserForm',
- 'name': user.name,
- 'email': user.email,
- 'password': user.password,
- 'project': self.tenant.id,
- 'role_id': self.roles.first().id,
- 'confirm_password': "doesntmatch"}
-
- res = self.client.post(USER_CREATE_URL, formData)
-
- self.assertFormError(res, "form", None, ['Passwords do not match.'])
-
- @test.create_stubs({api.keystone: ('tenant_list',
- 'role_list',
- 'get_default_role')})
- def test_create_validation_for_password_too_short(self):
- user = self.users.get(id="1")
-
- api.keystone.tenant_list(IgnoreArg(), user=None) \
- .AndReturn([self.tenants.list(), False])
- api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
- api.keystone.get_default_role(IgnoreArg()) \
- .AndReturn(self.roles.first())
-
- self.mox.ReplayAll()
-
- # check password min-len verification
- formData = {'method': 'CreateUserForm',
- 'name': user.name,
- 'email': user.email,
- 'password': 'four',
- 'project': self.tenant.id,
- 'role_id': self.roles.first().id,
- 'confirm_password': 'four'}
-
- res = self.client.post(USER_CREATE_URL, formData)
-
- self.assertFormError(
- res, "form", 'password',
- ['Password must be between 8 and 18 characters.'])
-
- @test.create_stubs({api.keystone: ('tenant_list',
- 'role_list',
- 'get_default_role')})
- def test_create_validation_for_password_too_long(self):
- user = self.users.get(id="1")
-
- api.keystone.tenant_list(IgnoreArg(), user=None) \
- .AndReturn([self.tenants.list(), False])
- api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
- api.keystone.get_default_role(IgnoreArg()) \
- .AndReturn(self.roles.first())
-
- self.mox.ReplayAll()
-
- # check password min-len verification
- formData = {'method': 'CreateUserForm',
- 'name': user.name,
- 'email': user.email,
- 'password': 'MoreThanEighteenChars',
- 'project': self.tenant.id,
- 'role_id': self.roles.first().id,
- 'confirm_password': 'MoreThanEighteenChars'}
-
- res = self.client.post(USER_CREATE_URL, formData)
-
- self.assertFormError(
- res, "form", 'password',
- ['Password must be between 8 and 18 characters.'])
-
- @test.create_stubs({api.keystone: ('user_get',
- 'tenant_list',
- 'user_update_tenant',
- 'user_update_password',
- 'user_update',
- 'roles_for_user', )})
- def test_update(self):
- user = self.users.get(id="1")
- test_password = 'normalpwd'
-
- api.keystone.user_get(IsA(http.HttpRequest), '1',
- admin=True).AndReturn(user)
- api.keystone.tenant_list(IgnoreArg(), user=user.id) \
- .AndReturn([self.tenants.list(), False])
- api.keystone.user_update(IsA(http.HttpRequest),
- user.id,
- email=u'test@example.com',
- name=u'test_user',
- password=test_password,
- project=self.tenant.id).AndReturn(None)
-
- self.mox.ReplayAll()
-
- formData = {'method': 'UpdateUserForm',
- 'id': user.id,
- 'name': user.name,
- 'email': user.email,
- 'password': test_password,
- 'project': self.tenant.id,
- 'confirm_password': test_password}
-
- res = self.client.post(USER_UPDATE_URL, formData)
-
- self.assertNoFormErrors(res)
-
- @test.create_stubs({api.keystone: ('user_get',
- 'tenant_list',
- 'user_update_tenant',
- 'keystone_can_edit_user',
- 'roles_for_user', )})
- def test_update_with_keystone_can_edit_user_false(self):
- user = self.users.get(id="1")
-
- api.keystone.user_get(IsA(http.HttpRequest),
- '1',
- admin=True).AndReturn(user)
- api.keystone.tenant_list(IgnoreArg(), user=user.id) \
- .AndReturn([self.tenants.list(), False])
- api.keystone.keystone_can_edit_user().AndReturn(False)
- api.keystone.keystone_can_edit_user().AndReturn(False)
-
- self.mox.ReplayAll()
-
- formData = {'method': 'UpdateUserForm',
- 'id': user.id,
- 'name': user.name,
- 'project': self.tenant.id, }
-
- res = self.client.post(USER_UPDATE_URL, formData)
-
- self.assertNoFormErrors(res)
- self.assertMessageCount(error=1)
-
- @test.create_stubs({api.keystone: ('user_get', 'tenant_list')})
- def test_update_validation_for_password_too_short(self):
- user = self.users.get(id="1")
-
- api.keystone.user_get(IsA(http.HttpRequest), '1',
- admin=True).AndReturn(user)
- api.keystone.tenant_list(IgnoreArg(), user=user.id) \
- .AndReturn([self.tenants.list(), False])
-
- self.mox.ReplayAll()
-
- formData = {'method': 'UpdateUserForm',
- 'id': user.id,
- 'name': user.name,
- 'email': user.email,
- 'password': 't',
- 'project': self.tenant.id,
- 'confirm_password': 't'}
-
- res = self.client.post(USER_UPDATE_URL, formData)
-
- self.assertFormError(
- res, "form", 'password',
- ['Password must be between 8 and 18 characters.'])
-
- @test.create_stubs({api.keystone: ('user_get', 'tenant_list')})
- def test_update_validation_for_password_too_long(self):
- user = self.users.get(id="1")
-
- api.keystone.user_get(IsA(http.HttpRequest), '1',
- admin=True).AndReturn(user)
- api.keystone.tenant_list(IgnoreArg(), user=user.id) \
- .AndReturn([self.tenants.list(), False])
-
- self.mox.ReplayAll()
-
- formData = {'method': 'UpdateUserForm',
- 'id': user.id,
- 'name': user.name,
- 'email': user.email,
- 'password': 'ThisIsASuperLongPassword',
- 'project': self.tenant.id,
- 'confirm_password': 'ThisIsASuperLongPassword'}
-
- res = self.client.post(USER_UPDATE_URL, formData)
-
- self.assertFormError(
- res, "form", 'password',
- ['Password must be between 8 and 18 characters.'])
-
- @test.create_stubs({api.keystone: ('user_update_enabled', 'user_list')})
- def test_enable_user(self):
- user = self.users.get(id="2")
- domain_id = self._get_domain_id()
- users = self._get_users(domain_id)
- user.enabled = False
-
- api.keystone.user_list(IgnoreArg(), domain=domain_id).AndReturn(users)
- api.keystone.user_update_enabled(IgnoreArg(),
- user.id,
- True).AndReturn(user)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'users__toggle__%s' % user.id}
- res = self.client.post(USERS_INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
-
- @test.create_stubs({api.keystone: ('user_update_enabled', 'user_list')})
- def test_disable_user(self):
- user = self.users.get(id="2")
- domain_id = self._get_domain_id()
- users = self._get_users(domain_id)
-
- self.assertTrue(user.enabled)
-
- api.keystone.user_list(IgnoreArg(), domain=domain_id) \
- .AndReturn(users)
- api.keystone.user_update_enabled(IgnoreArg(),
- user.id,
- False).AndReturn(user)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'users__toggle__%s' % user.id}
- res = self.client.post(USERS_INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
-
- @test.create_stubs({api.keystone: ('user_update_enabled', 'user_list')})
- def test_enable_disable_user_exception(self):
- user = self.users.get(id="2")
- domain_id = self._get_domain_id()
- users = self._get_users(domain_id)
- user.enabled = False
-
- api.keystone.user_list(IgnoreArg(), domain=domain_id) \
- .AndReturn(users)
- api.keystone.user_update_enabled(IgnoreArg(), user.id, True) \
- .AndRaise(self.exceptions.keystone)
- self.mox.ReplayAll()
-
- formData = {'action': 'users__toggle__%s' % user.id}
- res = self.client.post(USERS_INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
-
- @test.create_stubs({api.keystone: ('user_list',)})
- def test_disabling_current_user(self):
- domain_id = self._get_domain_id()
- users = self._get_users(domain_id)
- for i in range(0, 2):
- api.keystone.user_list(IgnoreArg(), domain=domain_id) \
- .AndReturn(users)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'users__toggle__%s' % self.request.user.id}
- res = self.client.post(USERS_INDEX_URL, formData, follow=True)
-
- self.assertEqual(list(res.context['messages'])[0].message,
- u'You cannot disable the user you are currently '
- u'logged in as.')
-
- @test.create_stubs({api.keystone: ('user_list',)})
- def test_delete_user_with_improper_permissions(self):
- domain_id = self._get_domain_id()
- users = self._get_users(domain_id)
- for i in range(0, 2):
- api.keystone.user_list(IgnoreArg(), domain=domain_id) \
- .AndReturn(users)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'users__delete__%s' % self.request.user.id}
- res = self.client.post(USERS_INDEX_URL, formData, follow=True)
-
- self.assertEqual(list(res.context['messages'])[0].message,
- u'You do not have permission to delete user: %s'
- % self.request.user.username)
-
-
-class SeleniumTests(test.SeleniumAdminTestCase):
- @test.create_stubs({api.keystone: ('tenant_list',
- 'get_default_role',
- 'role_list',
- 'user_list')})
- def test_modal_create_user_with_passwords_not_matching(self):
- api.keystone.tenant_list(IgnoreArg(), user=None) \
- .AndReturn([self.tenants.list(), False])
- api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
- api.keystone.user_list(IgnoreArg(), domain=None) \
- .AndReturn(self.users.list())
- api.keystone.get_default_role(IgnoreArg()) \
- .AndReturn(self.roles.first())
- self.mox.ReplayAll()
-
- self.selenium.get("%s%s" % (self.live_server_url, USERS_INDEX_URL))
-
- # Open the modal menu
- self.selenium.find_element_by_id("users__action_create") \
- .send_keys("\n")
- wait = self.ui.WebDriverWait(self.selenium, 10,
- ignored_exceptions=[socket_timeout])
- wait.until(lambda x: self.selenium.find_element_by_id("id_name"))
-
- body = self.selenium.find_element_by_tag_name("body")
- self.assertFalse("Passwords do not match" in body.text,
- "Error message should not be visible at loading time")
- self.selenium.find_element_by_id("id_name").send_keys("Test User")
- self.selenium.find_element_by_id("id_password").send_keys("test")
- self.selenium.find_element_by_id("id_confirm_password").send_keys("te")
- self.selenium.find_element_by_id("id_email").send_keys("a@b.com")
- body = self.selenium.find_element_by_tag_name("body")
- self.assertTrue("Passwords do not match" in body.text,
- "Error message not found in body")
-
- @test.create_stubs({api.keystone: ('tenant_list', 'user_get')})
- def test_update_user_with_passwords_not_matching(self):
- api.keystone.user_get(IsA(http.HttpRequest), '1',
- admin=True).AndReturn(self.user)
- api.keystone.tenant_list(IgnoreArg(), user=self.user.id) \
- .AndReturn([self.tenants.list(), False])
- self.mox.ReplayAll()
-
- self.selenium.get("%s%s" % (self.live_server_url, USER_UPDATE_URL))
-
- body = self.selenium.find_element_by_tag_name("body")
- self.assertFalse("Passwords do not match" in body.text,
- "Error message should not be visible at loading time")
- self.selenium.find_element_by_id("id_password").send_keys("test")
- self.selenium.find_element_by_id("id_confirm_password").send_keys("te")
- self.selenium.find_element_by_id("id_email").clear()
- body = self.selenium.find_element_by_tag_name("body")
- self.assertTrue("Passwords do not match" in body.text,
- "Error message not found in body")
diff --git a/openstack_dashboard/dashboards/admin/users/urls.py b/openstack_dashboard/dashboards/admin/users/urls.py
deleted file mode 100644
index 3387f5b2..00000000
--- a/openstack_dashboard/dashboards/admin/users/urls.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.users.views import CreateView
-from openstack_dashboard.dashboards.admin.users.views import IndexView
-from openstack_dashboard.dashboards.admin.users.views import UpdateView
-
-urlpatterns = patterns('openstack_dashboard.dashboards.admin.users.views',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^(?P<user_id>[^/]+)/update/$', UpdateView.as_view(), name='update'),
- url(r'^create/$', CreateView.as_view(), name='create'))
diff --git a/openstack_dashboard/dashboards/admin/users/views.py b/openstack_dashboard/dashboards/admin/users/views.py
deleted file mode 100644
index a0c32596..00000000
--- a/openstack_dashboard/dashboards/admin/users/views.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import operator
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django.utils.decorators import method_decorator
-from django.utils.translation import ugettext_lazy as _
-from django.views.decorators.debug import sensitive_post_parameters
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.admin.users.forms import CreateUserForm
-from openstack_dashboard.dashboards.admin.users.forms import UpdateUserForm
-from openstack_dashboard.dashboards.admin.users.tables import UsersTable
-
-
-class IndexView(tables.DataTableView):
- table_class = UsersTable
- template_name = 'admin/users/index.html'
-
- def get_data(self):
- users = []
- domain_context = self.request.session.get('domain_context', None)
- try:
- users = api.keystone.user_list(self.request,
- domain=domain_context)
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve user list.'))
- return users
-
-
-class UpdateView(forms.ModalFormView):
- form_class = UpdateUserForm
- template_name = 'admin/users/update.html'
- success_url = reverse_lazy('horizon:admin:users:index')
-
- @method_decorator(sensitive_post_parameters('password',
- 'confirm_password'))
- def dispatch(self, *args, **kwargs):
- return super(UpdateView, self).dispatch(*args, **kwargs)
-
- def get_object(self):
- if not hasattr(self, "_object"):
- try:
- self._object = api.keystone.user_get(self.request,
- self.kwargs['user_id'],
- admin=True)
- except:
- redirect = reverse("horizon:admin:users:index")
- exceptions.handle(self.request,
- _('Unable to update user.'),
- redirect=redirect)
- return self._object
-
- def get_context_data(self, **kwargs):
- context = super(UpdateView, self).get_context_data(**kwargs)
- context['user'] = self.get_object()
- return context
-
- def get_initial(self):
- user = self.get_object()
- return {'id': user.id,
- 'name': user.name,
- 'project': user.project_id,
- 'email': user.email}
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateUserForm
- template_name = 'admin/users/create.html'
- success_url = reverse_lazy('horizon:admin:users:index')
-
- @method_decorator(sensitive_post_parameters('password',
- 'confirm_password'))
- def dispatch(self, *args, **kwargs):
- return super(CreateView, self).dispatch(*args, **kwargs)
-
- def get_form_kwargs(self):
- kwargs = super(CreateView, self).get_form_kwargs()
- try:
- roles = api.keystone.role_list(self.request)
- except:
- redirect = reverse("horizon:admin:users:index")
- exceptions.handle(self.request,
- _("Unable to retrieve user roles."),
- redirect=redirect)
- roles.sort(key=operator.attrgetter("id"))
- kwargs['roles'] = roles
- return kwargs
-
- def get_initial(self):
- default_role = api.keystone.get_default_role(self.request)
- return {'role_id': getattr(default_role, "id", None)}
diff --git a/openstack_dashboard/dashboards/admin/volumes/__init__.py b/openstack_dashboard/dashboards/admin/volumes/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/admin/volumes/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/admin/volumes/forms.py b/openstack_dashboard/dashboards/admin/volumes/forms.py
deleted file mode 100644
index 9d0886fc..00000000
--- a/openstack_dashboard/dashboards/admin/volumes/forms.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard.api import cinder
-
-
-class CreateVolumeType(forms.SelfHandlingForm):
- name = forms.CharField(max_length="255", label=_("Name"))
-
- def handle(self, request, data):
- try:
- # Remove any new lines in the public key
- volume_type = cinder.volume_type_create(request,
- data['name'])
- messages.success(request, _('Successfully created volume type: %s')
- % data['name'])
- return volume_type
- except:
- exceptions.handle(request,
- _('Unable to create volume type.'))
- return False
diff --git a/openstack_dashboard/dashboards/admin/volumes/panel.py b/openstack_dashboard/dashboards/admin/volumes/panel.py
deleted file mode 100644
index 0a0eba49..00000000
--- a/openstack_dashboard/dashboards/admin/volumes/panel.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.admin import dashboard
-
-
-class Volumes(horizon.Panel):
- name = _("Volumes")
- slug = "volumes"
- permissions = ('openstack.services.volume',)
-
-
-dashboard.Admin.register(Volumes)
diff --git a/openstack_dashboard/dashboards/admin/volumes/tables.py b/openstack_dashboard/dashboards/admin/volumes/tables.py
deleted file mode 100644
index cbf300a6..00000000
--- a/openstack_dashboard/dashboards/admin/volumes/tables.py
+++ /dev/null
@@ -1,69 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-from openstack_dashboard.api import cinder
-from openstack_dashboard.dashboards.project.volumes.tables import \
- DeleteVolume
-from openstack_dashboard.dashboards.project.volumes.tables import \
- UpdateRow
-from openstack_dashboard.dashboards.project.volumes.tables import \
- VolumesTable as _VolumesTable
-
-
-class CreateVolumeType(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Volume Type")
- url = "horizon:admin:volumes:create_type"
- classes = ("ajax-modal", "btn-create")
-
-
-class DeleteVolumeType(tables.DeleteAction):
- data_type_singular = _("Volume Type")
- data_type_plural = _("Volume Types")
-
- def delete(self, request, obj_id):
- cinder.volume_type_delete(request, obj_id)
-
-
-class VolumesFilterAction(tables.FilterAction):
-
- def filter(self, table, volumes, filter_string):
- """ Naive case-insensitive search. """
- q = filter_string.lower()
- return [volume for volume in volumes
- if q in volume.display_name.lower()]
-
-
-class VolumesTable(_VolumesTable):
- name = tables.Column("display_name",
- verbose_name=_("Name"),
- link="horizon:admin:volumes:detail")
- host = tables.Column("os-vol-host-attr:host", verbose_name=_("Host"))
- tenant = tables.Column("tenant_name", verbose_name=_("Project"))
-
- class Meta:
- name = "volumes"
- verbose_name = _("Volumes")
- status_columns = ["status"]
- row_class = UpdateRow
- table_actions = (DeleteVolume, VolumesFilterAction)
- row_actions = (DeleteVolume,)
- columns = ('tenant', 'host', 'name', 'size', 'status', 'volume_type',
- 'attachments',)
-
-
-class VolumeTypesTable(tables.DataTable):
- name = tables.Column("name",
- verbose_name=_("Name"))
-
- def get_object_display(self, vol_type):
- return vol_type.name
-
- def get_object_id(self, vol_type):
- return str(vol_type.id)
-
- class Meta:
- name = "volume_types"
- verbose_name = _("Volume Types")
- table_actions = (CreateVolumeType, DeleteVolumeType,)
- row_actions = (DeleteVolumeType,)
diff --git a/openstack_dashboard/dashboards/admin/volumes/templates/volumes/_create_volume_type.html b/openstack_dashboard/dashboards/admin/volumes/templates/volumes/_create_volume_type.html
deleted file mode 100644
index 305093d3..00000000
--- a/openstack_dashboard/dashboards/admin/volumes/templates/volumes/_create_volume_type.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}{% endblock %}
-{% block form_action %}{% url 'horizon:admin:volumes:create_type' %}{% endblock %}
-
-{% block modal_id %}create_volume_type_modal{% endblock %}
-{% block modal-header %}{% trans "Create Volume Type" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% blocktrans %}
- The volume type defines the characteristics of a volume.
- It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.
- Examples: "Performance", "SSD", "Backup", etc.
- {% endblocktrans %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Volume Type" %}" />
- <a href="{% url 'horizon:admin:volumes:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/volumes/templates/volumes/create_volume_type.html b/openstack_dashboard/dashboards/admin/volumes/templates/volumes/create_volume_type.html
deleted file mode 100644
index d60b695d..00000000
--- a/openstack_dashboard/dashboards/admin/volumes/templates/volumes/create_volume_type.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Volume Type" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create a Volume Type") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'admin/volumes/_create_volume_type.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/volumes/templates/volumes/detail.html b/openstack_dashboard/dashboards/admin/volumes/templates/volumes/detail.html
deleted file mode 100644
index 9dbbd408..00000000
--- a/openstack_dashboard/dashboards/admin/volumes/templates/volumes/detail.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Volume Details" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Volume Detail") %}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/volumes/templates/volumes/index.html b/openstack_dashboard/dashboards/admin/volumes/templates/volumes/index.html
deleted file mode 100644
index 531571de..00000000
--- a/openstack_dashboard/dashboards/admin/volumes/templates/volumes/index.html
+++ /dev/null
@@ -1,17 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Volumes" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Volumes") %}
-{% endblock page_header %}
-
-{% block main %}
- <div id="volumes">
- {{ volumes_table.render }}
- </div>
-
- <div id="volume-types">
- {{ volume_types_table.render }}
- </div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/volumes/tests.py b/openstack_dashboard/dashboards/admin/volumes/tests.py
deleted file mode 100644
index 6c8473b4..00000000
--- a/openstack_dashboard/dashboards/admin/volumes/tests.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django import http
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.api import cinder
-from openstack_dashboard.api import keystone
-from openstack_dashboard.test import helpers as test
-
-
-class VolumeTests(test.BaseAdminViewTests):
- @test.create_stubs({api.nova: ('server_list',),
- cinder: ('volume_list',
- 'volume_type_list',),
- keystone: ('tenant_list',)})
- def test_index(self):
- cinder.volume_list(IsA(http.HttpRequest), search_opts={
- 'all_tenants': True}).AndReturn(self.volumes.list())
- api.nova.server_list(IsA(http.HttpRequest), search_opts={
- 'all_tenants': True}) \
- .AndReturn([self.servers.list(), False])
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- keystone.tenant_list(IsA(http.HttpRequest)) \
- .AndReturn([self.tenants.list(), False])
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:admin:volumes:index'))
-
- self.assertTemplateUsed(res, 'admin/volumes/index.html')
- volumes = res.context['volumes_table'].data
-
- self.assertItemsEqual(volumes, self.volumes.list())
-
- @test.create_stubs({cinder: ('volume_type_create',)})
- def test_create_volume_type(self):
- formData = {'name': 'volume type 1'}
- cinder.volume_type_create(IsA(http.HttpRequest),
- formData['name']).\
- AndReturn(self.volume_types.first())
- self.mox.ReplayAll()
-
- res = self.client.post(reverse('horizon:admin:volumes:create_type'),
- formData)
-
- redirect = reverse('horizon:admin:volumes:index')
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, redirect)
-
- @test.create_stubs({api.nova: ('server_list',),
- cinder: ('volume_list',
- 'volume_type_list',
- 'volume_type_delete',),
- keystone: ('tenant_list',)})
- def test_delete_volume_type(self):
- volume_type = self.volume_types.first()
- formData = {'action': 'volume_types__delete__%s' % volume_type.id}
-
- cinder.volume_list(IsA(http.HttpRequest), search_opts={
- 'all_tenants': True}).AndReturn(self.volumes.list())
- api.nova.server_list(IsA(http.HttpRequest), search_opts={
- 'all_tenants': True}) \
- .AndReturn([self.servers.list(), False])
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.volume_type_delete(IsA(http.HttpRequest),
- str(volume_type.id))
- keystone.tenant_list(IsA(http.HttpRequest)) \
- .AndReturn([self.tenants.list(), False])
- self.mox.ReplayAll()
-
- res = self.client.post(reverse('horizon:admin:volumes:index'),
- formData)
-
- redirect = reverse('horizon:admin:volumes:index')
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, redirect)
diff --git a/openstack_dashboard/dashboards/admin/volumes/urls.py b/openstack_dashboard/dashboards/admin/volumes/urls.py
deleted file mode 100644
index edcafe73..00000000
--- a/openstack_dashboard/dashboards/admin/volumes/urls.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.admin.volumes.views \
- import CreateVolumeTypeView
-from openstack_dashboard.dashboards.admin.volumes.views import DetailView
-from openstack_dashboard.dashboards.admin.volumes.views import IndexView
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^create_type$', CreateVolumeTypeView.as_view(), name='create_type'),
- url(r'^(?P<volume_id>[^/]+)/$', DetailView.as_view(), name='detail'),
-)
diff --git a/openstack_dashboard/dashboards/admin/volumes/views.py b/openstack_dashboard/dashboards/admin/volumes/views.py
deleted file mode 100644
index 7029b3ad..00000000
--- a/openstack_dashboard/dashboards/admin/volumes/views.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Admin views for managing volumes.
-"""
-
-from django.core.urlresolvers import reverse
-from django.utils.datastructures import SortedDict
-from django.utils.translation import ugettext_lazy as _
-
-from openstack_dashboard.dashboards.project.volumes.views import \
- DetailView as _DetailView
-from openstack_dashboard.dashboards.project.volumes.views import \
- VolumeTableMixIn
-
-from openstack_dashboard.api import cinder
-from openstack_dashboard.api import keystone
-
-from openstack_dashboard.dashboards.admin.volumes.forms import CreateVolumeType
-from openstack_dashboard.dashboards.admin.volumes.tables import VolumesTable
-from openstack_dashboard.dashboards.admin.volumes.tables \
- import VolumeTypesTable
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-
-
-class IndexView(tables.MultiTableView, VolumeTableMixIn):
- table_classes = (VolumesTable, VolumeTypesTable)
- template_name = "admin/volumes/index.html"
-
- def get_volumes_data(self):
- volumes = self._get_volumes(search_opts={'all_tenants': True})
- instances = self._get_instances(search_opts={'all_tenants': True})
- self._set_id_if_nameless(volumes, instances)
- self._set_attachments_string(volumes, instances)
-
- # Gather our tenants to correlate against IDs
- try:
- tenants, has_more = keystone.tenant_list(self.request)
- except:
- tenants = []
- msg = _('Unable to retrieve volume project information.')
- exceptions.handle(self.request, msg)
-
- tenant_dict = SortedDict([(t.id, t) for t in tenants])
- for volume in volumes:
- tenant_id = getattr(volume, "os-vol-tenant-attr:tenant_id", None)
- tenant = tenant_dict.get(tenant_id, None)
- volume.tenant_name = getattr(tenant, "name", None)
-
- return volumes
-
- def get_volume_types_data(self):
- try:
- volume_types = cinder.volume_type_list(self.request)
- except:
- volume_types = []
- exceptions.handle(self.request,
- _("Unable to retrieve volume types"))
- return volume_types
-
-
-class DetailView(_DetailView):
- template_name = "admin/volumes/detail.html"
-
-
-class CreateVolumeTypeView(forms.ModalFormView):
- form_class = CreateVolumeType
- template_name = 'admin/volumes/create_volume_type.html'
- success_url = 'horizon:admin:volumes:index'
-
- def get_success_url(self):
- return reverse(self.success_url)
diff --git a/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.capacity.js b/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.capacity.js
deleted file mode 100644
index c9cb4c0c..00000000
--- a/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.capacity.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- Used for animating and displaying capacity information using
- D3js progress bars.
-
- Usage:
- In order to have capacity bars that work with this, you need to have a
- DOM structure like this in your Django template:
-
- <div id="your_capacity_bar_id" class="capacity_bar">
- </div>
-
- With this capacity bar, you then need to add some data- HTML attributes
- to the div #your_capacity_bar_id. The available data- attributes are:
-
- data-chart-type="capacity_bar_chart" REQUIRED
- Must be "capacity_bar_chart".
-
- data-capacity-used="integer" OPTIONAL
- Integer representing the total number used by the user.
-
- data-capacity-limit="integer" OPTIONAL
- Integer representing the total quota limit the user has. Note this IS
- NOT the amount remaining they can use, but the total original capacity.
-
- data-average-capacity-used="integer" OPTIONAL
- Integer representing the average usage of given capacity.
-*/
-
-horizon.Capacity = {
- capacity_bars: [],
-
- // Determines the capacity bars to be used for capacity display.
- init: function() {
- this.capacity_bars = $('div[data-chart-type="capacity_bar_chart"]');
-
- // Draw the capacity bars
- this._initialCreation(this.capacity_bars);
- },
-
-
- /*
- Create a new d3 bar and populate it with the current amount used,
- average used, and percentage label
- */
- drawUsed: function(element, used_perc, used_px, average_perc) {
- var w= "100%";
- var h= 15;
- var lvl_curve= 3;
- var bkgrnd= "#F2F2F2";
- var frgrnd= "grey";
- var usage_color = d3.scale.linear()
- .domain([0, 50, 75, 90, 100])
- .range(["#669900", "#669900", "#FF9900", "#FF3300", "#CC0000"]);
-
- // Horizontal Bars
- var bar = d3.select("#"+element).append("svg:svg")
- .attr("class", "chart")
- .attr("width", w)
- .attr("height", h)
- .style("background-color", "white")
- .append("g");
-
- // background - unused resources
- bar.append("rect")
- .attr("y", 0)
- .attr("width", w)
- .attr("height", h)
- .attr("rx", lvl_curve)
- .attr("ry", lvl_curve)
- .style("fill", bkgrnd)
- .style("stroke", "#bebebe")
- .style("stroke-width", 1);
-
- // used resources
- if (used_perc) {
- bar.append("rect")
- .attr("class", "usedbar")
- .attr("y", 0)
- .attr("id", "test")
- .attr("width", 0)
- .attr("height", h)
- .attr("rx", lvl_curve)
- .attr("ry", lvl_curve)
- .style("fill", usage_color(used_perc))
- .style("stroke", "#a0a0a0")
- .style("stroke-width", 1)
- .attr("d", used_perc)
- .transition()
- .duration(500)
- .attr("width", used_perc + "%");
- }
-
- // average
- if (average_perc) {
- bar.append("rect")
- .attr("y",1)
- .attr("x", 0)
- .attr("class", "average")
- .attr("height", h-2)
- .attr("width", 1)
- .style("fill", "black")
- .transition()
- .duration(500)
- .attr("x", average_perc + "%");
- }
-
- // used text
- if (used_perc) {
- bar.append("text")
- .text(used_perc + "%")
- .attr("y", 8)
- .attr("x", 3)
- .attr("dominant-baseline", "middle")
- .attr("font-size", 10)
- .transition()
- .duration(500)
- .attr("x", function() {
- // position the percentage label
- if (used_perc > 99 && used_px > 25){
- return used_px - 30;
- } else if (used_px > 25) {
- return used_px - 25;
- } else {
- return used_px + 3;
- }
- });
- }
- },
-
-
- // Draw the initial d3 bars
- _initialCreation: function(bars) {
- var scope = this;
- $(bars).each(function(index, element) {
- var progress_element = $(element);
-
- var capacity_limit = parseInt(progress_element.attr('data-capacity-limit'), 10);
- var capacity_used = parseInt(progress_element.attr('data-capacity-used'), 10);
- var average_used = parseInt(progress_element.attr('data-average-capacity-used'), 10);
-
- if (!isNaN(capacity_limit) && !isNaN(average_used)) {
- var average_percentage = ((average_used / capacity_limit) * 100);
- } else {
- var average_percentage = 0;
- }
-
- if (!isNaN(capacity_limit) && !isNaN(capacity_used)) {
- var percentage_used = Math.round((capacity_used / capacity_limit) * 100);
- var used_px = progress_element.width() / 100 * percentage_used;
-
- } else { // If NaN percentage_used is 0
- var percentage_used = 0;
- var used_px = 0;
- }
-
- scope.drawUsed($(element).attr('id'), percentage_used, used_px, average_percentage);
- });
- }
-};
-
-horizon.addInitFunction(function () {
- horizon.Capacity.init();
-});
diff --git a/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3circleschart.js b/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3circleschart.js
deleted file mode 100644
index 305b2182..00000000
--- a/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3circleschart.js
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- Draw circles chart in d3.
-
- To use, a div is required with the data attributes
- data-chart-type="circles_chart", data-url and data-size in the
- div.
-
- data-chart-type - must be "circles_chart" so chart gets initialized
- data-url - (string) url for the json data for the chart
- data-time - (string) time parameter, gets appended to url as time=...
- data-size - (integer) size of the circles in pixels
-
- If used in popup, initialization must be made manually e.g.:
- addHorizonLoadEvent(function() {
- horizon.d3_circles_chart.init('.html_element');
- horizon.d3_circles_chart.init('.health_chart');
- });
-
-
- Example:
- <div class="html_element"
- data-chart-type="circles_chart"
- data-url="/infrastructure/racks/1/top_communicating.json?cond=to"
- data-time="now"
- data-size="22">
- </div>
-
- There are controll elements for the cirles chart, implementing some commands
- that will be executed over the chart.
-
- 1. The selectbox for time change, implements ChangeTime command. It has to
- have data attribute data-circles-chart-command="change_time", with defined
- receiver as jquery selector (selector can point to more elements and it will
- execute the command on all of them) e.g. data-receiver="#rack_health_chart"
- Option value is then appended to url and chart is refreshed.
-
- Example
- <div class="span3 circles_chart_time_picker">
- <select data-circles-chart-command="change_time"
- data-receiver="#rack_health_chart">
- <option value="now">Now</option>
- <option value="yesterday">Yesterday</option>
- <option value="last_week">Last Week</option>
- <option value="last_month">Last Month</option>
- </select>
- </div>
- <div class="clear"></div>
-
- 2. Bootstrap tabs for switching different circle_charts implement command
- ChangeUrl. It has to have data attribute data-circles-chart-command="change_url",
- with defined receiver as jquery selector (selector can point to more elements and
- it will execute the command on all of them) e.g. data-receiver="#rack_health_chart"
-
- Inner li a element has to have attribute data-url, e.g.
- data-url="/infrastructure/racks/1/top_communicating.json?type=alerts"
-
- The url of the chart is then switched and chart is refreshed.
-
- <ul class="nav nav-tabs"
- data-circles-chart-command="change_url"
- data-receiver="#rack_health_chart">
- <li class="active">
- <a data-url="/infrastructure/racks/1/top_communicating.json?type=overall_health" href="#">
- Overall Health</a>
- </li>
- <li>
- <a data-url="/infrastructure/racks/1/top_communicating.json?type=alerts" href="#">
- Alerts</a>
- </li>
- <li>
- <a data-url="/infrastructure/racks/1/top_communicating.json?type=capacities" href="#">
- Capacities</a>
- </li>
- <li>
- <a data-url="/infrastructure/racks/1/top_communicating.json?type=status" href="#">
- Status</a>
- </li>
- </ul>
-*/
-
-
-horizon.d3_circles_chart = {
- CirclesChart: function(chart_class, html_element){
- this.chart_class = chart_class;
- this.html_element = html_element;
-
- var jquery_element = $(html_element);
- this.size = jquery_element.data('size');
- this.time = jquery_element.data('time');
- this.url = jquery_element.data('url');
-
- this.final_url = this.url;
- if (this.final_url.indexOf('?') > -1){
- this.final_url += '&time=' + this.time;
- }else{
- this.final_url += '?time=' + this.time;
- }
-
- this.time = jquery_element.data('time');
- this.data = []
-
- this.refresh = refresh;
- function refresh(){
- var self = this;
- this.jqxhr = $.getJSON( this.final_url, function() {
- //FIXME add loader in the target element
- })
- .done(function(data) {
- // FIXME find a way how to only update graph with new data
- // not delete and create
- $(self.html_element).html("");
-
- self.data = data.data;
- self.settings = data.settings;
- self.chart_class.render(self.html_element, self.size, self.data, self.settings);
- })
- .fail(function() {
- // FIXME add proper fail message
- console.log( "error" ); })
- .always(function() {
- // FIXME add behaviour that should be always done
- });
- }
- },
- init: function(selector, settings) {
- var self = this;
- $(selector).each(function() {
- self.refresh(this);
- });
- self.bind_commands();
- },
- refresh: function(html_element){
- var chart = new this.CirclesChart(this, html_element)
- // FIXME save chart objects somewhere so I can use them again when
- // e.g. I am swithing tabs, or if I want to update them
- // via web sockets
- // this.charts.add_or_update(chart)
- chart.refresh();
- },
- render: function(html_element, size, data, settings){
- var self = this;
- // FIXME rewrite to scatter plot once we have some cool D3 chart
- // library
- var width = size + 4,
- height = size + 4,
- round = size / 2;
- center_x = width / 2,
- center_y = height / 2;
-
- var svg = d3.select(html_element).selectAll("svg")
- .data(data)
- .enter().append("svg")
- .attr("width", width)
- .attr("height", height);
-
- // FIXME use some pretty tooltip from some library we will use
- // this one is just temporary
- var tooltip = d3.select(html_element).append("div")
- .style("position", "absolute")
- .style("z-index", "10")
- .style("visibility", "hidden")
- .style("min-width", "100px")
- .style("max-width", "110px")
- .style("min-height", "30px")
- .style("border", "1px ridge grey")
- .style("background-color", "white")
- .text(function(d) { "a simple tooltip"; });
-
- var circle = svg.append("circle")
- .attr("r", round)//function(d) { return d.r; })// can be sent form server
- .attr("cx", center_x)
- .attr("cy", center_y)
- .attr("stroke", "#cecece")
- .attr("stroke-width", function(d) {
- return 1;
- })
- .style("fill", function(d) {
- if (d.color){
- return d.color;
- } else if (settings.scale == "linear_color_scale"){
- return self.linear_color_scale(d.percentage, settings.domain, settings.range)
-
- }
- })
- .on("mouseover", function(d){
- if (d.tooltip) {
- tooltip.html(d.tooltip);
- } else {
- tooltip.html(d.name + "<br/>" + d.status);
- }
- tooltip.style("visibility", "visible");})
- .on("mousemove", function(d){tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");})
- .on("mouseout", function(d){tooltip.style("visibility", "hidden");});
- ;
-
- /*
- // or just d3 title element
- circle.append("svg:title")
- .text(function(d) { return d.x; });
-
- */
- },
- linear_color_scale: function(percentage, domain, range){
- usage_color = d3.scale.linear()
- .domain(domain)
- .range(range);
- return usage_color(percentage);
- },
- bind_commands: function (){
- var change_time_command_selector = 'select[data-circles-chart-command="change_time"]';
- var change_url_command_selector = '[data-circles-chart-command="change_url"]';
- var self = this;
- bind_change_time = function(){
- $(change_time_command_selector).each(function() {
- $(this).change(function(){
- var invoker = $(this);
- var command = new self.Command.ChangeTime(self, invoker);
- command.execute();
- });
- });
- }
- bind_change_url = function(){
- $(change_url_command_selector + ' a').click(function (e) {
- // Bootstrap tabs functionality
- e.preventDefault();
- $(this).tab('show');
-
- // Command for url change and refresh
- var invoker = $(this);
- var command = new self.Command.ChangeUrl(self, invoker);
- command.execute();
- })
- }
- bind_change_time();
- bind_change_url();
- },
- Command: {
- ChangeTime: function (chart_class, invoker){
- // Invoker of the command should know about it's receiver.
- // Also invoker brings all parameters of the command.
- this.receiver_selector = invoker.data('receiver');
- this.new_time = invoker.find("option:selected").val();
-
- this.execute = execute;
- function execute(){
- var self = this;
- $(this.receiver_selector).each(function(){
- // change time of the chart
- $(this).data('time', self.new_time);
- // refresh the chart
- chart_class.refresh(this)
- });
- }
- },
- ChangeUrl: function (chart_class, invoker, new_url){
- // Invoker of the command should know about it's receiver.
- // Also invoker brings all parameters of the command.
- this.receiver_selector = invoker.parents('ul').first().data('receiver');
- this.new_url = invoker.data('url');
-
- this.execute = execute;
- function execute(){
- var self = this;
- $(this.receiver_selector).each(function(){
- // change time of the chart
- $(this).data('url', self.new_url);
- // refresh the chart
- chart_class.refresh(this)
- });
- }
- }
- }
-}
-
-/* init the graphs */
-horizon.addInitFunction(function () {
- horizon.d3_circles_chart.init('div[data-chart-type="circles_chart"]');
-});
-
diff --git a/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3linechart.js b/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3linechart.js
deleted file mode 100644
index f84cee82..00000000
--- a/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3linechart.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- Draw line chart in d3.
-
- It support 2 types of usage:
- * as a standard line chart
- * as a line chart in a modal window
-
- To use as a standard line chart the following data attributes need to be
- provided for a div:
- data-chart-type - must be "line_chart"
- data-url - (string) url for the json data for the chart
- data-series - (string) the list of series separated by comma
-
- Example:
- <div data-chart-type="line_chart"
- data-url="/data_url"
- data-series="cpu,ram,storage,network">
- </div>
-
- To use as a line chart in a modal windows the following data attributes
- need to be provided for a link:
- data-chart-type - must be "modal_line_chart"
- data-url - (string) url for the json data for the chart
- data-series - (string) the list of series separated by comma
-
- Example:
- <a data-chart-type="modal_line_chart"
- data-url="/data_url"
- data-series="network">
- Click me!
- </a>
-*/
-
-horizon.d3_line_chart = {
-
- init: function() {
- var self = this;
-
- self.init_line_charts();
- self.init_modal_chart_links();
- },
-
- init_line_charts: function() {
- var self = this;
-
- line_charts = $("div[data-chart-type='line_chart']");
- $.each(line_charts, function(index, line_chart) {
- if($(line_chart).data('modal') != true) {
- var template = horizon.templates.compiled_templates["#modal_chart_template"];
- self.init_svg(line_chart);
- self.draw(self.data(line_chart));
- }
- });
- },
-
- init_modal_chart_links: function() {
- var self = this;
-
- $(document).on('click', "a[data-chart-type='modal_line_chart']", function(event) {
- event.preventDefault();
-
- var template = horizon.templates.compiled_templates["#modal_chart_template"];
- $('#modal_wrapper').append(template.render({classes: "modal"}));
-
- var modal = $('.modal:last');
- modal.modal();
-
- $(modal).on('click', 'ul#interval_selector li a', function(event){
- event.preventDefault();
-
- self.url_options.interval = $(event.target).data('interval');
- self.draw(self.url_options);
- $("ul#interval_selector li").removeClass("active");
- $(event.target).parent().addClass("active");
- })
-
- self.init_svg("#modal_chart");
- self.url_options = self.data($(event.target))
- self.draw(self.url_options)
- });
- },
-
- init_svg: function(chart_div) {
- var self = this;
-
- self.margin = {top: 20, right: 80, bottom: 30, left: 50};
- self.width = 550 - self.margin.left - self.margin.right;
- self.height = 300 - self.margin.top - self.margin.bottom;
-
- self.svg = d3.select(chart_div)
- .append("svg")
- .attr("width", self.width + self.margin.left + self.margin.right)
- .attr("height", self.height + self.margin.top + self.margin.bottom)
- .append("g")
- .attr("transform", "translate(" + self.margin.left + "," + self.margin.top + ")");
-
- self.x = d3.time.scale().range([0, self.width]);
- self.y = d3.scale.linear().range([self.height, 0]);
-
- self.xAxis = d3.svg.axis()
- .scale(self.x)
- .orient("bottom").ticks(6);
- self.yAxis = d3.svg.axis()
- .scale(self.y)
- .orient("left");
-
- self.parse_date = d3.time.format("%Y-%m-%dT%H:%M:%S.%L").parse;
-
- self.line = d3.svg.line().interpolate("linear")
- .x(function(d) { return self.x(d.date); })
- .y(function(d) { return self.y(d.value); });
-
- self.color = d3.scale.category10();
- },
-
- draw: function(url_options) {
- var self = this;
- var url_options = url_options || {};
- url_options.interval = url_options.interval || "1w";
-
- d3.json(self.json_url(url_options), function(error, data) {
- data.forEach(function(d) { d.date = self.parse_date(d.date); });
-
- self.color.domain(d3.keys(data[0]).filter(function(key) { return key !== 'date'; }));
-
- var usage_values = self.color.domain().map(function(name) {
- return {
- name: name,
- values: data.map(function(d) {
- return {date: d.date, value: d[name]};
- })
- };
- });
-
- self.svg.selectAll(".axis").remove();
- self.x.domain(d3.extent(data, function(d) { return d.date; }));
- self.y.domain([0, 15]);
-
- self.svg.append("g")
- .attr("transform", "translate(0," + self.height + ")")
- .attr("class", "axis")
- .call(self.xAxis);
- self.svg.append("g")
- .attr("class", "axis")
- .call(self.yAxis)
-
- var usages = self.svg.selectAll(".usage")
- .data(usage_values, function(d) { return self.key(d) });
-
- var usage = usages.enter().append("g")
- .attr("class", "usage");
-
- usage.append("path")
- .attr("d", function(d) { return self.line(d.values); })
- .style("stroke", function(d) { return self.color(d.name); })
- .style("fill", "none")
- .style("stroke-width", 3);
-
- var legend = usage.append('g')
- .attr('class', 'legend');
-
- legend.append('rect')
- .attr('x', self.width - 60)
- .attr('y', function(d, i){ return (i * 20) + 30 ;})
- .attr('width', 10)
- .attr('height', 10)
- .style('fill', function(d) { return self.color(d.name); });
-
- legend.append('text')
- .attr('x', self.width - 40)
- .attr('y', function(d, i){ return (i * 20) + 39;})
- .text(function(d){ return d.name.replace(/_/g, " "); });
-
- usages.exit().remove();
- });
- },
-
- data: function(element) {
- return {
- url: $(element).data("url"),
- series: $(element).data("series")
- };
- },
-
- json_url: function(url_options) {
- var options = $.extend({}, url_options);
- var url = options.url
- delete options.url
- return url + '?' + $.param(options);
- },
-
- key: function(data){
- return data.name + data.values.length + data.values[0].date + data.values[data.values.length-1].date
- },
-
-};
-
-horizon.addInitFunction(function () {
- horizon.d3_line_chart.init();
-});
diff --git a/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3singlebarchart.js b/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3singlebarchart.js
deleted file mode 100644
index 5e89a0e7..00000000
--- a/openstack_dashboard/dashboards/infrastructure/static/infrastructure/js/horizon.d3singlebarchart.js
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- Used for animating and displaying single-bar information using
- D3js rect.
-
- Usage:
- In order to have single bars that work with this, you need to have a
- DOM structure like this in your Django template:
-
- Example:
- <div class="flavor_usage_bar"
- data-popup-free='<p>Capacity remaining by flavors: </p>
- {{resource_class.all_instances_flavors_info}}'
- data-single-bar-orientation="horizontal"
- data-single-bar-height="50"
- data-single-bar-width="100%"
- data-single-bar-used="{{ resource_class.all_used_instances_info }}"
- data-single-bar-auto-scale-selector=".flavors_scale_selector"
- data-single-bar-color-scale-range='["#000060", "#99FFFF"]'>
- </div>
-
- The available data- attributes are:
- data-popup-free, data-popup-used, data-popup-average OPTIONAL
- Html content of popups that will be displayed over this areas.
-
- data-single-bar-orientation REQUIRED
- String representing orientation of the bar.Can be "horizontal"
- or "vertical"
-
- data-single-bar-height REQUIRED
- Integer or string with percent mark format e.g. "50%". Determines
- the total height of the bar.
-
- data-single-bar-width="100%" REQUIRED
- Integer or string with percent mark format e.g. "50%". Determines
- the total width of the bar.
-
- data-single-bar-used="integer" REQUIRED
- 1. Integer
- Integer representing the percent used.
- 2. Array
- Array of following structure:
- [{"popup_used": "Popup html 1", "used_instances": "5"},
- {"popup_used": "Popup html 2", "used_instances": "15"},....]
-
- used_instances: Integer representing the percent used.
- popup_used: Html that will be displayed in popup window over
- this area.
-
- data-single-bar-used-average="integer" OPTIONAL
- Integer representing the average usage in percent of given
- single-bar.
-
- data-single-bar-auto-scale-selector OPTIONAL
- Jquery selector of bar elements that have Integer
- data-single-bar-used attribute. It then takes maximum of these
- values as 100% of the liner scale of the colors.
- So the array representing linear scale interval is set
- automatically.This then maps to data-single-bar-color-scale-range.
- (arrays must have the same structure)
-
- single-bar-color-scale-range OPTIONAL
- Array representing linear scale interval that is set manually.
- E.g "[0,10]". This then maps to data-single-bar-color-scale-range.
- (arrays must have the same structure)
-
- data-single-bar-color-scale-range OPTIONAL
- Array representing linear scale of colors.
- E.g '["#000060", "#99FFFF"]'
-
-*/
-
-horizon.d3_single_bar_chart = {
- SingleBarChart: function(chart_class, html_element){
- var self = this;
- self.chart_class = chart_class;
-
- self.html_element = html_element;
- self.jquery_element = $(self.html_element);
- // Using only percent, so limit is 100%
- self.single_bar_limit = 100;
-
- self.single_bar_used = $.parseJSON(self.jquery_element.attr('data-single-bar-used'));
- self.average_used = parseInt(self.jquery_element.attr('data-single-bar-average-used'), 10);
-
- self.data = {};
-
- // Percentage and used_px count
- if ($.isArray(self.single_bar_used)){
- self.data.used_px = 0;
- self.data.percentage_used = Array();
- self.data.tooltip_used_contents = Array();
- for (var i = 0; i < self.single_bar_used.length; ++i) {
- if (!isNaN(self.single_bar_limit) && !isNaN(self.single_bar_used[i].used_instances)) {
- used = Math.round((self.single_bar_used[i].used_instances / self.single_bar_limit) * 100);
-
- self.data.percentage_used.push(used);
- // for multi-bar chart, tooltip is in the data
- self.data.tooltip_used_contents.push(self.single_bar_used[i].popup_used);
-
- self.data.used_px += self.jquery_element.width() / 100 * used;
- } else { // If NaN self.data.percentage_used is 0
-
- }
- }
-
- }
- else {
- if (!isNaN(self.single_bar_limit) && !isNaN(self.single_bar_used)) {
- self.data.percentage_used = Math.round((self.single_bar_used / self.single_bar_limit) * 100);
- self.data.used_px = self.jquery_element.width() / 100 * self.data.percentage_used;
-
- } else { // If NaN self.data.percentage_used is 0
- self.data.percentage_used = 0;
- self.data.used_px = 0;
- }
-
- if (!isNaN(self.single_bar_limit) && !isNaN(self.average_used)) {
- self.data.percentage_average = ((self.average_used / self.single_bar_limit) * 100);
- } else {
- self.data.percentage_average = 0;
- }
- }
-
- // Width and height of bar
- self.data.width = self.jquery_element.data('single-bar-width');
- self.data.height = self.jquery_element.data('single-bar-height');
-
- // Color scales
- self.auto_scale_selector = function () {
- return self.jquery_element.data('single-bar-auto-scale-selector');
- };
- self.is_auto_scaling = function () {
- return self.auto_scale_selector();
- };
- self.auto_scale = function () {
- var max_scale = 0;
- $(self.auto_scale_selector()).each(function() {
- var scale = parseInt($(this).data('single-bar-used'));
- if (scale > max_scale)
- max_scale = scale;
- });
- return [0, max_scale];
- };
-
- if (self.jquery_element.data('single-bar-color-scale-domain'))
- self.data.color_scale_domain =
- self.jquery_element.data('single-bar-color-scale-domain');
- else if (self.is_auto_scaling())
- // Dynamically set scale based on biggest value
- self.data.color_scale_domain = self.auto_scale();
- else
- self.data.color_scale_domain = [0,100];
-
- if (self.jquery_element.data('single-bar-color-scale-range'))
- self.data.color_scale_range =
- self.jquery_element.data('single-bar-color-scale-range');
- else
- self.data.color_scale_range = ["#000000", "#0000FF"];
-
- // Tooltips data
- self.data.popup_average = self.jquery_element.data('popup-average');
- self.data.popup_free = self.jquery_element.data('popup-free');
- self.data.popup_used = self.jquery_element.data('popup-used');
-
- // Orientation of the Bar chart
- self.data.orientation = self.jquery_element.data('single-bar-orientation');
-
- // Refresh method
- self.refresh = function (){
- self.chart_class.render(self.html_element, self.data);
- };
- },
- BaseComponent: function(data){
- var self = this;
-
- self.data = data;
-
- self.w = data.width;
- self.h = data.height;
- self.lvl_curve = 3;
- self.bkgrnd = "#F2F2F2";
- self.frgrnd = "grey";
- self.color_scale_max = 25;
-
- self.percentage_used = data.percentage_used;
- self.total_used_perc = 0;
- self.used_px = data.used_px;
- self.percentage_average = data.percentage_average;
- self.tooltip_used_contents = data.tooltip_used_contents;
-
- // set scales
- self.usage_color = d3.scale.linear()
- .domain(data.color_scale_domain)
- .range(data.color_scale_range);
-
- // return true if it renders used percentage multiple in one chart
- self.used_multi = function (){
- return ($.isArray(self.percentage_used));
- };
-
- // deals with percentage if there should be multiple in one chart
- self.used_multi_iterator = 0;
- self.percentage_used_value = function(){
- if (self.used_multi()){
- return self.percentage_used[self.used_multi_iterator];
- } else {
- return self.percentage_used;
- }
- };
- // deals with html tooltips if there should be multiple in one chart
- self.tooltip_used_value = function (){
- if (self.used_multi()){
- return self.tooltip_used_contents[self.used_multi_iterator];
- } else {
- return "";
- }
- };
-
- // return true if it chart is oriented horizontally
- self.horizontal_orientation = function (){
- return (self.data.orientation == "horizontal");
- };
-
- },
- UsedComponent: function(base_component){
- var self = this;
- self.base_component = base_component;
-
- // FIXME woud be good to abstract all atributes and resolve orientation inside
- if (base_component.horizontal_orientation()){
- // Horizontal Bars
- self.y = 0;
- self.x = base_component.total_used_perc + "%";
- self.width = 0;
- self.height = base_component.h;
- self.trasition_attr = "width";
- self.trasition_value = base_component.percentage_used_value() + "%";
- } else { // Vertical Bars
- self.y = base_component.h;
- self.x = 0;
- self.width = base_component.w;
- self.height = base_component.percentage_used_value() + "%";
- self.trasition_attr = "y";
- self.trasition_value = 100 - base_component.percentage_used_value() + "%";
- }
-
- self.append = function(bar, tooltip){
- var used_component = self;
- var base_component = self.base_component;
-
- bar.append("rect")
- .attr("class", "usedbar")
- .attr("y", used_component.y)
- .attr("x", used_component.x)
- .attr("width", used_component.width)
- .attr("height", used_component.height)
- //.attr("rx", base_component.lvl_curve)
- //.attr("ry", base_component.lvl_curve)
- .style("fill", base_component.usage_color(base_component.percentage_used_value()))
- .style("stroke", "#bebebe")
- .style("stroke-width", 0)
- .attr("d", base_component.percentage_used_value())
- .attr("popup-used", base_component.tooltip_used_value())
- .on("mouseover", function(d){
- if ($(this).attr('popup-used')){
- tooltip.html($(this).attr('popup-used'));
- }
- tooltip.style("visibility", "visible");})
- .on("mousemove", function(d){tooltip.style("top",
- (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");})
- .on("mouseout", function(d){tooltip.style("visibility", "hidden");})
- .transition()
- .duration(500)
- .attr(used_component.trasition_attr, used_component.trasition_value);
- };
- },
- AverageComponent: function(base_component){
- var self = this;
- self.base_component = base_component;
-
- // FIXME woud be good to abstract all atributes and resolve orientation inside
- if (base_component.horizontal_orientation()){
- // Horizontal Bars
- self.y = 1;
- self.x = 0;
- self.width = 1;
- self.height = base_component.h;
- self.trasition_attr = "x";
- self.trasition_value = base_component.percentage_average + "%";
- } else { // Vertical Bars
- self.y = 0;
- self.x = 0;
- self.width = base_component.w;
- self.height = 1;
- self.trasition_attr = "y";
- self.trasition_value = 100 - base_component.percentage_average + "%";
- }
-
- self.append = function(bar, tooltip){
- var average_component = self;
- var base_component = self.base_component;
-
- bar.append("rect")
- .attr("y", average_component.y)
- .attr("x", average_component.x)
- .attr("class", "average")
- .attr("height", average_component.height)
- .attr("width", average_component.width)
- .style("fill", "black")
- .on("mouseover", function(){tooltip.style("visibility", "visible");})
- .on("mousemove", function(){tooltip.style("top",
- (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");})
- .on("mouseout", function(){tooltip.style("visibility", "hidden");})
- .transition()
- .duration(500)
- .attr(average_component.trasition_attr, average_component.trasition_value);
- };
- },
- /* TODO rewrite below as components */
- /* FIXME use some pretty tooltip from some library we will use
- * this one is just temporary */
- append_tooltip: function(tooltip, html_content){
- return tooltip
- .style("position", "absolute")
- .style("z-index", "10")
- .style("visibility", "hidden")
- .style("min-width", "100px")
- .style("max-width", "200px")
- .style("min-height", "30px")
- .style("max-height", "150px")
- .style("border", "1px ridge grey")
- .style("padding", "8px")
- .style("padding-top", "5px")
- .style("background-color", "white")
- .html(html_content);
- },
- append_unused: function(bar, base_component, tooltip_free){
- bar.append("rect")
- .attr("y", 0)
- .attr("width", base_component.w)
- .attr("height", base_component.h)
- .attr("rx", base_component.lvl_curve)
- .attr("ry", base_component.lvl_curve)
- .style("fill", base_component.bkgrnd)
- .style("stroke", "#e0e0e0")
- .style("stroke-width", 1)
- .on("mouseover", function(d){tooltip_free.style("visibility", "visible");})
- .on("mousemove", function(d){tooltip_free.style("top",
- (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");})
- .on("mouseout", function(d){tooltip_free.style("visibility", "hidden");});
- },
- // TODO This have to be enhanced, so this library can replace jtomasek capacity charts
- append_text: function(bar, base_component, tooltip){
- bar.append("text")
- .text("FREE")
- .attr("y", base_component.h/2)
- .attr("x", 3)
- .attr("dominant-baseline", "middle")
- .attr("font-size", 13)
- .on("mouseover", function(d){tooltip.style("visibility", "visible");})
- .on("mousemove", function(d){tooltip.style("top",
- (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");})
- .on("mouseout", function(d){tooltip.style("visibility", "hidden");})
- .transition()
- .duration(500)
- .attr("x", function() {
- // FIXME when another panel is active, this page is hidden and used_px return 0
- // text is then badly positioned, quick fix will be to refresh charts when panel
- // is switched. Need to find better solution.
- if (base_component.total_used_perc > 90 && base_component.used_px > 25)
- return base_component.used_px - 20;
- else
- return base_component.used_px + 20;
- });
- },
- append_border: function(bar){
- bar.append("rect")
- .attr("x", 0)
- .attr("y", 0)
- .attr("height", '100%')
- .attr("width", '100%')
- .style("stroke", "#bebebe")
- .style("fill", "none")
- .style("stroke-width", 1);
- },
- // INIT
- init: function() {
- var self = this;
- this.single_bars = $('div[data-single-bar-used]');
-
- this.single_bars.each(function() {
- self.refresh(this);
- });
- },
- refresh: function(html_element){
- var chart = new this.SingleBarChart(this, html_element);
- // FIXME save chart objects somewhere so I can use them again when
- // e.g. I am swithing tabs, or if I want to update them
- // via web sockets
- // this.charts.add_or_update(chart)
- chart.refresh();
- },
- render: function(html_element, data) {
- var jquery_element = $(html_element);
-
- // Initialize base_component
- var base_component = new this.BaseComponent(data);
-
- // Bar
- var bar_html = d3.select(html_element);
-
- // Tooltips
- var tooltip_average = bar_html.append("div");
- if (data.popup_average)
- tooltip_average = this.append_tooltip(tooltip_average, data.popup_average);
-
- var tooltip_free = bar_html.append("div");
- if (data.popup_free)
- tooltip_free = this.append_tooltip(tooltip_free, data.popup_free);
-
- var tooltip_used = bar_html.append("div");
- if (data.popup_used)
- tooltip_used = this.append_tooltip(tooltip_used, data.popup_used);
-
- // append layout for bar chart
- var bar = bar_html.append("svg:svg")
- .attr("class", "chart")
- .attr("width", base_component.w)
- .attr("height", base_component.h)
- .style("background-color", "white")
- .append("g");
-
- // append Unused resources Bar
- this.append_unused(bar, base_component, tooltip_free);
-
- if (base_component.used_multi()){
- // If Used is shown as multiple values in one chart
- for (var i = 0; i < base_component.percentage_used.length; ++i) {
- // FIXME write proper iterator
- base_component.used_multi_iterator = i;
-
- // Use general tooltip, content of tooltip will be changed
- // by inner used compoentnts on their hover
- tooltip_used = this.append_tooltip(tooltip_used, "");
-
- // append used so it will be shown as multiple values in one chart
- var used_component = new this.UsedComponent(base_component);
- used_component.append(bar, tooltip_used);
-
- // append Used resources to Bar
- base_component.total_used_perc += base_component.percentage_used_value();
- };
-
- // append Text to Bar
- this.append_text(bar, base_component, tooltip_free);
-
- } else {
- // used is show as one value it the chart
- var used_component = new this.UsedComponent(base_component);
- used_component.append(bar, tooltip_used);
-
- // append average value to Bar
- var average_component = new this.AverageComponent(base_component);
- average_component.append(bar, tooltip_average);
- }
- // append border of whole Bar
- this.append_border(bar);
- },
-};
-
-
-horizon.addInitFunction(function () {
- horizon.d3_single_bar_chart.init();
-});
diff --git a/openstack_dashboard/dashboards/infrastructure/templates/infrastructure/_scripts.html b/openstack_dashboard/dashboards/infrastructure/templates/infrastructure/_scripts.html
deleted file mode 100644
index 44cc82b1..00000000
--- a/openstack_dashboard/dashboards/infrastructure/templates/infrastructure/_scripts.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends 'horizon/_scripts.html' %}
-{% block custom_js_files %}
- <script src='{{ STATIC_URL }}infrastructure/js/horizon.capacity.js' type='text/javascript' charset='utf-8'></script>
- <script src='{{ STATIC_URL }}infrastructure/js/horizon.d3circleschart.js' type='text/javascript' charset='utf-8'></script>
- <script src='{{ STATIC_URL }}infrastructure/js/horizon.d3linechart.js' type='text/javascript' charset='utf-8'></script>
- <script src='{{ STATIC_URL }}infrastructure/js/horizon.d3singlebarchart.js' type='text/javascript' charset='utf-8'></script>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/__init__.py b/openstack_dashboard/dashboards/project/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/access_and_security/__init__.py b/openstack_dashboard/dashboards/project/access_and_security/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/access_and_security/api_access/__init__.py b/openstack_dashboard/dashboards/project/access_and_security/api_access/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/api_access/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/access_and_security/api_access/tables.py b/openstack_dashboard/dashboards/project/access_and_security/api_access/tables.py
deleted file mode 100644
index 88f171a7..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/api_access/tables.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.template.defaultfilters import title
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-
-def pretty_service_names(name):
- name = name.replace('-', ' ')
- if name in ['ec2', 's3']:
- name = name.upper()
- else:
- name = title(name)
- return name
-
-
-class DownloadEC2(tables.LinkAction):
- name = "download_ec2"
- verbose_name = _("Download EC2 Credentials")
- verbose_name_plural = _("Download EC2 Credentials")
- classes = ("btn-download",)
- url = "horizon:project:access_and_security:api_access:ec2"
-
-
-class DownloadOpenRC(tables.LinkAction):
- name = "download_openrc"
- verbose_name = _("Download OpenStack RC File")
- verbose_name_plural = _("Download OpenStack RC File")
- classes = ("btn-download",)
- url = "horizon:project:access_and_security:api_access:openrc"
-
-
-class EndpointsTable(tables.DataTable):
- api_name = tables.Column('type',
- verbose_name=_("Service"),
- filters=(pretty_service_names,))
- api_endpoint = tables.Column('public_url',
- verbose_name=_("Service Endpoint"))
-
- class Meta:
- name = "endpoints"
- verbose_name = _("API Endpoints")
- multi_select = False
- table_actions = (DownloadOpenRC, DownloadEC2,)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/api_access/tests.py b/openstack_dashboard/dashboards/project/access_and_security/api_access/tests.py
deleted file mode 100644
index a01a0775..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/api_access/tests.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula Inc
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django.http import HttpRequest
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-EC2_URL = reverse("horizon:project:access_and_security:api_access:ec2")
-
-
-class APIAccessTests(test.TestCase):
- def test_ec2_download_view(self):
- creds = self.ec2.first()
- cert = self.certs.first()
-
- self.mox.StubOutWithMock(api.keystone, "list_ec2_credentials")
- self.mox.StubOutWithMock(api.nova, "get_x509_credentials")
- self.mox.StubOutWithMock(api.nova, "get_x509_root_certificate")
- self.mox.StubOutWithMock(api.keystone, "create_ec2_credentials")
-
- api.keystone.list_ec2_credentials(IsA(HttpRequest), self.user.id) \
- .AndReturn([])
- api.nova.get_x509_credentials(IsA(HttpRequest)).AndReturn(cert)
- api.nova.get_x509_root_certificate(IsA(HttpRequest)) \
- .AndReturn(cert)
- api.keystone.create_ec2_credentials(IsA(HttpRequest),
- self.user.id,
- self.tenant.id).AndReturn(creds)
- self.mox.ReplayAll()
-
- res = self.client.get(EC2_URL)
- self.assertEqual(res.status_code, 200)
- self.assertEqual(res['content-type'], 'application/zip')
diff --git a/openstack_dashboard/dashboards/project/access_and_security/api_access/urls.py b/openstack_dashboard/dashboards/project/access_and_security/api_access/urls.py
deleted file mode 100644
index dad12e96..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/api_access/urls.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.access_and_security.\
- api_access.views import download_ec2_bundle
-from openstack_dashboard.dashboards.project.access_and_security.\
- api_access.views import download_rc_file
-
-
-urlpatterns = patterns('',
- url(r'^ec2/$', download_ec2_bundle, name='ec2'),
- url(r'^openrc/$', download_rc_file, name='openrc'),
-)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/api_access/views.py b/openstack_dashboard/dashboards/project/access_and_security/api_access/views.py
deleted file mode 100644
index 9fc33008..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/api_access/views.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Openstack, LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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 contextlib import closing
-import logging
-import tempfile
-import zipfile
-
-from django import http
-from django import shortcuts
-from django.template.loader import render_to_string
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-def download_ec2_bundle(request):
- tenant_id = request.user.tenant_id
- tenant_name = request.user.tenant_name
-
- # Gather or create our EC2 credentials
- try:
- credentials = api.nova.get_x509_credentials(request)
- cacert = api.nova.get_x509_root_certificate(request)
-
- all_keys = api.keystone.list_ec2_credentials(request,
- request.user.id)
- keys = None
- for key in all_keys:
- if key.tenant_id == tenant_id:
- keys = key
- if keys is None:
- keys = api.keystone.create_ec2_credentials(request,
- request.user.id,
- tenant_id)
- except:
- exceptions.handle(request,
- _('Unable to fetch EC2 credentials.'),
- redirect=request.build_absolute_uri())
-
- # Get our S3 endpoint if it exists
- try:
- s3_endpoint = api.base.url_for(request,
- 's3',
- endpoint_type='publicURL')
- except exceptions.ServiceCatalogException:
- s3_endpoint = None
-
- # Get our EC2 endpoint (it should exist since we just got creds for it)
- try:
- ec2_endpoint = api.base.url_for(request,
- 'ec2',
- endpoint_type='publicURL')
- except exceptions.ServiceCatalogException:
- ec2_endpoint = None
-
- # Build the context
- context = {'ec2_access_key': keys.access,
- 'ec2_secret_key': keys.secret,
- 'ec2_endpoint': ec2_endpoint,
- 's3_endpoint': s3_endpoint}
-
- # Create our file bundle
- template = 'project/access_and_security/api_access/ec2rc.sh.template'
- try:
- temp_zip = tempfile.NamedTemporaryFile(delete=True)
- with closing(zipfile.ZipFile(temp_zip.name, mode='w')) as archive:
- archive.writestr('pk.pem', credentials.private_key)
- archive.writestr('cert.pem', credentials.data)
- archive.writestr('cacert.pem', cacert.data)
- archive.writestr('ec2rc.sh', render_to_string(template, context))
- except:
- exceptions.handle(request,
- _('Error writing zipfile: %(exc)s'),
- redirect=request.build_absolute_uri())
-
- # Send it back
- response = http.HttpResponse(mimetype='application/zip')
- response.write(temp_zip.read())
- response['Content-Disposition'] = ('attachment; '
- 'filename=%s-x509.zip'
- % tenant_name)
- response['Content-Length'] = temp_zip.tell()
- return response
-
-
-def download_rc_file(request):
- tenant_id = request.user.tenant_id
- tenant_name = request.user.tenant_name
-
- template = 'project/access_and_security/api_access/openrc.sh.template'
-
- try:
- keystone_url = api.base.url_for(request,
- 'identity',
- endpoint_type='publicURL')
-
- context = {'user': request.user,
- 'auth_url': keystone_url,
- 'tenant_id': tenant_id,
- 'tenant_name': tenant_name}
-
- response = shortcuts.render(request,
- template,
- context,
- content_type="text/plain")
- response['Content-Disposition'] = ('attachment; '
- 'filename=%s-openrc.sh'
- % tenant_name)
- response['Content-Length'] = str(len(response.content))
- return response
-
- except Exception as e:
- LOG.exception("Exception in DownloadOpenRCForm.")
- messages.error(request, _('Error Downloading RC File: %s') % e)
- return shortcuts.redirect(request.build_absolute_uri())
diff --git a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/__init__.py b/openstack_dashboard/dashboards/project/access_and_security/floating_ips/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/forms.py b/openstack_dashboard/dashboards/project/access_and_security/floating_ips/forms.py
deleted file mode 100644
index 40918f78..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/forms.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-# Copyright (c) 2012 X.commerce, a business unit of eBay Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-class FloatingIpAllocate(forms.SelfHandlingForm):
- pool = forms.ChoiceField(label=_("Pool"))
-
- def __init__(self, *args, **kwargs):
- super(FloatingIpAllocate, self).__init__(*args, **kwargs)
- floating_pool_list = kwargs.get('initial', {}).get('pool_list', [])
- self.fields['pool'].choices = floating_pool_list
-
- def handle(self, request, data):
- try:
- fip = api.network.tenant_floating_ip_allocate(request,
- pool=data['pool'])
- messages.success(request,
- _('Allocated Floating IP %(ip)s.')
- % {"ip": fip.ip})
- return fip
- except:
- exceptions.handle(request, _('Unable to allocate Floating IP.'))
diff --git a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/tables.py b/openstack_dashboard/dashboards/project/access_and_security/floating_ips/tables.py
deleted file mode 100644
index 751ce681..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/tables.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-# Copyright (c) 2012 X.commerce, a business unit of eBay Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core import urlresolvers
-from django import shortcuts
-from django.utils.http import urlencode
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import messages
-from horizon import tables
-
-from openstack_dashboard import api
-from openstack_dashboard.utils.filters import get_int_or_uuid
-
-
-LOG = logging.getLogger(__name__)
-
-
-class AllocateIP(tables.LinkAction):
- name = "allocate"
- verbose_name = _("Allocate IP To Project")
- classes = ("ajax-modal", "btn-allocate")
- url = "horizon:project:access_and_security:floating_ips:allocate"
-
- def single(self, data_table, request, *args):
- return shortcuts.redirect('horizon:project:access_and_security:index')
-
-
-class ReleaseIPs(tables.BatchAction):
- name = "release"
- action_present = _("Release")
- action_past = _("Released")
- data_type_singular = _("Floating IP")
- data_type_plural = _("Floating IPs")
- classes = ('btn-danger', 'btn-release')
-
- def action(self, request, obj_id):
- api.network.tenant_floating_ip_release(request, obj_id)
-
-
-class AssociateIP(tables.LinkAction):
- name = "associate"
- verbose_name = _("Associate")
- url = "horizon:project:access_and_security:floating_ips:associate"
- classes = ("ajax-modal", "btn-associate")
-
- def allowed(self, request, fip):
- if fip.port_id:
- return False
- return True
-
- def get_link_url(self, datum):
- base_url = urlresolvers.reverse(self.url)
- params = urlencode({"ip_id": self.table.get_object_id(datum)})
- return "?".join([base_url, params])
-
-
-class DisassociateIP(tables.Action):
- name = "disassociate"
- verbose_name = _("Disassociate")
- classes = ("btn-disassociate", "btn-danger")
-
- def allowed(self, request, fip):
- if fip.port_id:
- return True
- return False
-
- def single(self, table, request, obj_id):
- try:
- fip = table.get_object_by_id(get_int_or_uuid(obj_id))
- api.network.floating_ip_disassociate(request, fip.id,
- fip.port_id)
- LOG.info('Disassociating Floating IP "%s".' % obj_id)
- messages.success(request,
- _('Successfully disassociated Floating IP: %s')
- % fip.ip)
- except:
- exceptions.handle(request,
- _('Unable to disassociate floating IP.'))
- return shortcuts.redirect('horizon:project:access_and_security:index')
-
-
-def get_instance_info(instance):
- return getattr(instance, "instance_name", None)
-
-
-def get_instance_link(datum):
- view = "horizon:project:instances:detail"
- if datum.instance_id:
- return urlresolvers.reverse(view, args=(datum.instance_id,))
- else:
- return None
-
-
-class FloatingIPsTable(tables.DataTable):
- ip = tables.Column("ip",
- verbose_name=_("IP Address"),
- attrs={'data-type': "ip"})
- instance = tables.Column(get_instance_info,
- link=get_instance_link,
- verbose_name=_("Instance"),
- empty_value="-")
- pool = tables.Column("pool_name",
- verbose_name=_("Floating IP Pool"),
- empty_value="-")
-
- def sanitize_id(self, obj_id):
- return get_int_or_uuid(obj_id)
-
- def get_object_display(self, datum):
- return datum.ip
-
- class Meta:
- name = "floating_ips"
- verbose_name = _("Floating IPs")
- table_actions = (AllocateIP, ReleaseIPs)
- row_actions = (AssociateIP, DisassociateIP, ReleaseIPs)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/tests.py b/openstack_dashboard/dashboards/project/access_and_security/floating_ips/tests.py
deleted file mode 100644
index 2b2036e9..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/tests.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-# Copyright (c) 2012 X.commerce, a business unit of eBay Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-from horizon.workflows.views import WorkflowView
-
-
-INDEX_URL = reverse('horizon:project:access_and_security:index')
-NAMESPACE = "horizon:project:access_and_security:floating_ips"
-
-
-class FloatingIpViewTests(test.TestCase):
- def test_associate(self):
- self.mox.StubOutWithMock(api.network, 'floating_ip_target_list')
- self.mox.StubOutWithMock(api.network, 'tenant_floating_ip_list')
- api.network.floating_ip_target_list(IsA(http.HttpRequest)) \
- .AndReturn(self.servers.list())
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn(self.floating_ips.list())
- self.mox.ReplayAll()
-
- url = reverse('%s:associate' % NAMESPACE)
- res = self.client.get(url)
- self.assertTemplateUsed(res, WorkflowView.template_name)
- workflow = res.context['workflow']
- choices = dict(workflow.steps[0].action.fields['ip_id'].choices)
- # Verify that our "associated" floating IP isn't in the choices list.
- self.assertTrue(self.floating_ips.first() not in choices)
-
- def test_associate_post(self):
- floating_ip = self.floating_ips.list()[1]
- server = self.servers.first()
- self.mox.StubOutWithMock(api.network, 'floating_ip_associate')
- self.mox.StubOutWithMock(api.network, 'tenant_floating_ip_list')
- self.mox.StubOutWithMock(api.network, 'floating_ip_target_list')
-
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn(self.floating_ips.list())
- api.network.floating_ip_target_list(IsA(http.HttpRequest)) \
- .AndReturn(self.servers.list())
- api.network.floating_ip_associate(IsA(http.HttpRequest),
- floating_ip.id,
- server.id)
- self.mox.ReplayAll()
-
- form_data = {'instance_id': server.id,
- 'ip_id': floating_ip.id}
- url = reverse('%s:associate' % NAMESPACE)
- res = self.client.post(url, form_data)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_associate_post_with_redirect(self):
- floating_ip = self.floating_ips.list()[1]
- server = self.servers.first()
- self.mox.StubOutWithMock(api.network, 'floating_ip_associate')
- self.mox.StubOutWithMock(api.network, 'tenant_floating_ip_list')
- self.mox.StubOutWithMock(api.network, 'floating_ip_target_list')
-
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn(self.floating_ips.list())
- api.network.floating_ip_target_list(IsA(http.HttpRequest)) \
- .AndReturn(self.servers.list())
- api.network.floating_ip_associate(IsA(http.HttpRequest),
- floating_ip.id,
- server.id)
- self.mox.ReplayAll()
-
- form_data = {'instance_id': server.id,
- 'ip_id': floating_ip.id}
- url = reverse('%s:associate' % NAMESPACE)
- next = reverse("horizon:project:instances:index")
- res = self.client.post("%s?next=%s" % (url, next), form_data)
- self.assertRedirectsNoFollow(res, next)
-
- def test_associate_post_with_exception(self):
- floating_ip = self.floating_ips.list()[1]
- server = self.servers.first()
- self.mox.StubOutWithMock(api.network, 'floating_ip_associate')
- self.mox.StubOutWithMock(api.network, 'tenant_floating_ip_list')
- self.mox.StubOutWithMock(api.network, 'floating_ip_target_list')
-
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn(self.floating_ips.list())
- api.network.floating_ip_target_list(IsA(http.HttpRequest)) \
- .AndReturn(self.servers.list())
- api.network.floating_ip_associate(IsA(http.HttpRequest),
- floating_ip.id,
- server.id) \
- .AndRaise(self.exceptions.nova)
- self.mox.ReplayAll()
-
- form_data = {'instance_id': server.id,
- 'ip_id': floating_ip.id}
- url = reverse('%s:associate' % NAMESPACE)
- res = self.client.post(url, form_data)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_disassociate_post(self):
- floating_ip = self.floating_ips.first()
- server = self.servers.first()
- self.mox.StubOutWithMock(api.network, 'tenant_floating_ip_list')
- self.mox.StubOutWithMock(api.network, 'tenant_floating_ip_get')
- self.mox.StubOutWithMock(api.network, 'floating_ip_disassociate')
- self.mox.StubOutWithMock(api.nova, 'server_list')
-
- api.nova.server_list(IsA(http.HttpRequest)) \
- .AndReturn([self.servers.list(), False])
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn(self.floating_ips.list())
- api.network.floating_ip_disassociate(IsA(http.HttpRequest),
- floating_ip.id,
- server.id)
- self.mox.ReplayAll()
-
- action = "floating_ips__disassociate__%s" % floating_ip.id
- res = self.client.post(INDEX_URL, {"action": action})
- self.assertMessageCount(success=1)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_disassociate_post_with_exception(self):
- floating_ip = self.floating_ips.first()
- server = self.servers.first()
- self.mox.StubOutWithMock(api.network, 'tenant_floating_ip_list')
- self.mox.StubOutWithMock(api.network, 'tenant_floating_ip_get')
- self.mox.StubOutWithMock(api.network, 'floating_ip_disassociate')
- self.mox.StubOutWithMock(api.nova, 'server_list')
-
- api.nova.server_list(IsA(http.HttpRequest)) \
- .AndReturn([self.servers.list(), False])
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn(self.floating_ips.list())
-
- api.network.floating_ip_disassociate(IsA(http.HttpRequest),
- floating_ip.id,
- server.id) \
- .AndRaise(self.exceptions.nova)
- self.mox.ReplayAll()
-
- action = "floating_ips__disassociate__%s" % floating_ip.id
- res = self.client.post(INDEX_URL, {"action": action})
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
-
-class FloatingIpNeutronViewTests(FloatingIpViewTests):
- def setUp(self):
- super(FloatingIpViewTests, self).setUp()
- self._floating_ips_orig = self.floating_ips
- self.floating_ips = self.floating_ips_uuid
-
- def tearDown(self):
- self.floating_ips = self._floating_ips_orig
- super(FloatingIpViewTests, self).tearDown()
diff --git a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/urls.py b/openstack_dashboard/dashboards/project/access_and_security/floating_ips/urls.py
deleted file mode 100644
index 57ecf507..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/urls.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.access_and_security.\
- floating_ips.views import AllocateView
-from openstack_dashboard.dashboards.project.access_and_security.\
- floating_ips.views import AssociateView
-
-
-urlpatterns = patterns('',
- url(r'^associate/$', AssociateView.as_view(), name='associate'),
- url(r'^allocate/$', AllocateView.as_view(), name='allocate')
-)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/views.py b/openstack_dashboard/dashboards/project/access_and_security/floating_ips/views.py
deleted file mode 100644
index abaf04f6..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/views.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-# Copyright (c) 2012 X.commerce, a business unit of eBay Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing floating IPs.
-"""
-
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import workflows
-
-from openstack_dashboard import api
-from openstack_dashboard.usage import quotas
-
-from openstack_dashboard.dashboards.project.access_and_security.\
- floating_ips.forms import FloatingIpAllocate
-from openstack_dashboard.dashboards.project.access_and_security.\
- floating_ips.workflows import IPAssociationWorkflow
-
-
-class AssociateView(workflows.WorkflowView):
- workflow_class = IPAssociationWorkflow
-
-
-class AllocateView(forms.ModalFormView):
- form_class = FloatingIpAllocate
- template_name = 'project/access_and_security/floating_ips/allocate.html'
- success_url = reverse_lazy('horizon:project:access_and_security:index')
-
- def get_object_display(self, obj):
- return obj.ip
-
- def get_context_data(self, **kwargs):
- context = super(AllocateView, self).get_context_data(**kwargs)
- try:
- context['usages'] = quotas.tenant_quota_usages(self.request)
- except:
- exceptions.handle(self.request)
- return context
-
- def get_initial(self):
- try:
- pools = api.network.floating_ip_pools_list(self.request)
- except:
- pools = []
- exceptions.handle(self.request,
- _("Unable to retrieve floating IP pools."))
- pool_list = [(pool.id, pool.name) for pool in pools]
- if not pool_list:
- pool_list = [(None, _("No floating IP pools available."))]
- return {'pool_list': pool_list}
diff --git a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/workflows.py b/openstack_dashboard/dashboards/project/access_and_security/floating_ips/workflows.py
deleted file mode 100644
index 77fb9545..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/floating_ips/workflows.py
+++ /dev/null
@@ -1,143 +0,0 @@
-
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import workflows
-
-from openstack_dashboard import api
-from openstack_dashboard.utils.filters import get_int_or_uuid
-
-
-ALLOCATE_URL = "horizon:project:access_and_security:floating_ips:allocate"
-
-
-class AssociateIPAction(workflows.Action):
- ip_id = forms.DynamicTypedChoiceField(label=_("IP Address"),
- coerce=get_int_or_uuid,
- empty_value=None,
- add_item_link=ALLOCATE_URL)
- instance_id = forms.ChoiceField(label=_("Instance"))
-
- class Meta:
- name = _("IP Address")
- help_text = _("Select the IP address you wish to associate with "
- "the selected instance.")
-
- def __init__(self, *args, **kwargs):
- super(AssociateIPAction, self).__init__(*args, **kwargs)
- if api.base.is_service_enabled(self.request, 'network'):
- label = _("Port to be associated")
- else:
- label = _("Instance to be associated")
- self.fields['instance_id'].label = label
-
- # If AssociateIP is invoked from instance menu, instance_id parameter
- # is passed in URL. In Neutron based Floating IP implementation
- # an association target is not an instance but a port, so we need
- # to get an association target based on a received instance_id
- # and set the initial value of instance_id ChoiceField.
- q_instance_id = self.request.GET.get('instance_id')
- if q_instance_id:
- target_id = api.network.floating_ip_target_get_by_instance(
- self.request, q_instance_id)
- self.initial['instance_id'] = target_id
-
- def populate_ip_id_choices(self, request, context):
- try:
- ips = api.network.tenant_floating_ip_list(self.request)
- except:
- redirect = reverse('horizon:project:access_and_security:index')
- exceptions.handle(self.request,
- _('Unable to retrieve floating IP addresses.'),
- redirect=redirect)
- options = sorted([(ip.id, ip.ip) for ip in ips if not ip.port_id])
- if options:
- options.insert(0, ("", _("Select an IP address")))
- else:
- options = [("", _("No IP addresses available"))]
-
- return options
-
- def populate_instance_id_choices(self, request, context):
- try:
- targets = api.network.floating_ip_target_list(self.request)
- except:
- redirect = reverse('horizon:project:access_and_security:index')
- exceptions.handle(self.request,
- _('Unable to retrieve instance list.'),
- redirect=redirect)
- instances = []
- for target in targets:
- instances.append((target.id, target.name))
-
- # Sort instances for easy browsing
- instances = sorted(instances, key=lambda x: x[1])
-
- neutron_enabled = api.base.is_service_enabled(request, 'network')
- if instances:
- if neutron_enabled:
- label = _("Select a port")
- else:
- label = _("Select an instance")
- instances.insert(0, ("", label))
- else:
- if neutron_enabled:
- label = _("No ports available")
- else:
- label = _("No instances available")
- instances = (("", label),)
- return instances
-
-
-class AssociateIP(workflows.Step):
- action_class = AssociateIPAction
- contributes = ("ip_id", "instance_id", "ip_address")
-
- def contribute(self, data, context):
- context = super(AssociateIP, self).contribute(data, context)
- ip_id = data.get('ip_id', None)
- if ip_id:
- ip_choices = dict(self.action.fields['ip_id'].choices)
- context["ip_address"] = ip_choices.get(ip_id, None)
- return context
-
-
-class IPAssociationWorkflow(workflows.Workflow):
- slug = "ip_association"
- name = _("Manage Floating IP Associations")
- finalize_button_name = _("Associate")
- success_message = _('IP address %s associated.')
- failure_message = _('Unable to associate IP address %s.')
- success_url = "horizon:project:access_and_security:index"
- default_steps = (AssociateIP,)
-
- def format_status_message(self, message):
- return message % self.context.get('ip_address', 'unknown IP address')
-
- def handle(self, request, data):
- try:
- api.network.floating_ip_associate(request,
- data['ip_id'],
- data['instance_id'])
- except:
- exceptions.handle(request)
- return False
- return True
diff --git a/openstack_dashboard/dashboards/project/access_and_security/keypairs/__init__.py b/openstack_dashboard/dashboards/project/access_and_security/keypairs/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/keypairs/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/access_and_security/keypairs/forms.py b/openstack_dashboard/dashboards/project/access_and_security/keypairs/forms.py
deleted file mode 100644
index dfab3f6c..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/keypairs/forms.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import re
-
-from django.core import validators
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-NEW_LINES = re.compile(r"\r|\n")
-
-
-class CreateKeypair(forms.SelfHandlingForm):
- name = forms.CharField(max_length="20",
- label=_("Keypair Name"),
- validators=[validators.validate_slug],
- error_messages={'invalid': _('Keypair names may '
- 'only contain letters, numbers, underscores '
- 'and hyphens.')})
-
- def handle(self, request, data):
- return True # We just redirect to the download view.
-
-
-class ImportKeypair(forms.SelfHandlingForm):
- name = forms.CharField(max_length="20", label=_("Keypair Name"),
- validators=[validators.RegexValidator('\w+')])
- public_key = forms.CharField(label=_("Public Key"), widget=forms.Textarea)
-
- def handle(self, request, data):
- try:
- # Remove any new lines in the public key
- data['public_key'] = NEW_LINES.sub("", data['public_key'])
- keypair = api.nova.keypair_import(request,
- data['name'],
- data['public_key'])
- messages.success(request, _('Successfully imported public key: %s')
- % data['name'])
- return keypair
- except:
- exceptions.handle(request, ignore=True)
- self.api_error(_('Unable to import keypair.'))
- return False
diff --git a/openstack_dashboard/dashboards/project/access_and_security/keypairs/tables.py b/openstack_dashboard/dashboards/project/access_and_security/keypairs/tables.py
deleted file mode 100644
index fdec467d..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/keypairs/tables.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DeleteKeyPairs(tables.DeleteAction):
- data_type_singular = _("Keypair")
- data_type_plural = _("Keypairs")
-
- def delete(self, request, obj_id):
- api.nova.keypair_delete(request, obj_id)
-
-
-class ImportKeyPair(tables.LinkAction):
- name = "import"
- verbose_name = _("Import Keypair")
- url = "horizon:project:access_and_security:keypairs:import"
- classes = ("ajax-modal", "btn-upload")
-
-
-class CreateKeyPair(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Keypair")
- url = "horizon:project:access_and_security:keypairs:create"
- classes = ("ajax-modal", "btn-create")
-
-
-class KeypairsTable(tables.DataTable):
- name = tables.Column("name", verbose_name=_("Keypair Name"))
- fingerprint = tables.Column("fingerprint", verbose_name=_("Fingerprint"))
-
- def get_object_id(self, keypair):
- return keypair.name
-
- class Meta:
- name = "keypairs"
- verbose_name = _("Keypairs")
- table_actions = (CreateKeyPair, ImportKeyPair, DeleteKeyPairs,)
- row_actions = (DeleteKeyPairs,)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/keypairs/tests.py b/openstack_dashboard/dashboards/project/access_and_security/keypairs/tests.py
deleted file mode 100644
index bdb12452..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/keypairs/tests.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-INDEX_VIEW_URL = reverse('horizon:project:access_and_security:index')
-
-
-class KeyPairViewTests(test.TestCase):
- def test_delete_keypair(self):
- keypair = self.keypairs.first()
-
- self.mox.StubOutWithMock(api.nova, 'keypair_list')
- self.mox.StubOutWithMock(api.nova, 'keypair_delete')
-
- api.nova.keypair_list(IsA(http.HttpRequest)) \
- .AndReturn(self.keypairs.list())
- api.nova.keypair_delete(IsA(http.HttpRequest), keypair.name)
- self.mox.ReplayAll()
-
- formData = {'action': 'keypairs__delete__%s' % keypair.name}
- res = self.client.post(INDEX_VIEW_URL, formData)
- self.assertRedirectsNoFollow(res, INDEX_VIEW_URL)
-
- def test_delete_keypair_exception(self):
- keypair = self.keypairs.first()
- self.mox.StubOutWithMock(api.nova, 'keypair_list')
- self.mox.StubOutWithMock(api.nova, 'keypair_delete')
-
- api.nova.keypair_list(IsA(http.HttpRequest)) \
- .AndReturn(self.keypairs.list())
- api.nova.keypair_delete(IsA(http.HttpRequest), keypair.name) \
- .AndRaise(self.exceptions.nova)
- self.mox.ReplayAll()
-
- formData = {'action': 'keypairs__delete__%s' % keypair.name}
- res = self.client.post(INDEX_VIEW_URL, formData)
- self.assertRedirectsNoFollow(res, INDEX_VIEW_URL)
-
- def test_create_keypair_get(self):
- res = self.client.get(
- reverse('horizon:project:access_and_security:keypairs:create'))
- self.assertTemplateUsed(res,
- 'project/access_and_security/keypairs/create.html')
-
- def test_download_keypair_get(self):
- keypair_name = "keypair"
- context = {'keypair_name': keypair_name}
- url = reverse('horizon:project:access_and_security:keypairs:download',
- kwargs={'keypair_name': keypair_name})
- res = self.client.get(url, context)
- self.assertTemplateUsed(
- res, 'project/access_and_security/keypairs/download.html')
-
- def test_generate_keypair_get(self):
- keypair = self.keypairs.first()
- keypair.private_key = "secret"
-
- self.mox.StubOutWithMock(api.nova, 'keypair_create')
- api.nova.keypair_create(IsA(http.HttpRequest),
- keypair.name).AndReturn(keypair)
- self.mox.ReplayAll()
-
- context = {'keypair_name': keypair.name}
- url = reverse('horizon:project:access_and_security:keypairs:generate',
- kwargs={'keypair_name': keypair.name})
- res = self.client.get(url, context)
-
- self.assertTrue(res.has_header('content-disposition'))
-
- @test.create_stubs({api.nova: ("keypair_import",)})
- def test_import_keypair(self):
- key1_name = "new key pair"
- public_key = "ssh-rsa ABCDEFGHIJKLMNOPQR\r\n" \
- "STUVWXYZ1234567890\r" \
- "XXYYZZ user@computer\n\n"
- api.nova.keypair_import(IsA(http.HttpRequest), key1_name,
- public_key.replace("\r", "").replace("\n", ""))
- self.mox.ReplayAll()
-
- formData = {'method': 'ImportKeypair',
- 'name': key1_name,
- 'public_key': public_key}
- url = reverse('horizon:project:access_and_security:keypairs:import')
- res = self.client.post(url, formData)
- self.assertMessageCount(res, success=1)
-
- def test_import_keypair_invalid_key(self):
- key_name = "new key pair"
- public_key = "ABCDEF"
-
- self.mox.StubOutWithMock(api.nova, 'keypair_import')
- api.nova.keypair_import(IsA(http.HttpRequest), key_name, public_key) \
- .AndRaise(self.exceptions.nova)
- self.mox.ReplayAll()
-
- formData = {'method': 'ImportKeypair',
- 'name': key_name,
- 'public_key': public_key}
- url = reverse('horizon:project:access_and_security:keypairs:import')
- res = self.client.post(url, formData, follow=True)
- self.assertEqual(res.redirect_chain, [])
- msg = 'Unable to import keypair.'
- self.assertFormErrors(res, count=1, message=msg)
-
- def test_generate_keypair_exception(self):
- keypair = self.keypairs.first()
-
- self.mox.StubOutWithMock(api.nova, 'keypair_create')
- api.nova.keypair_create(IsA(http.HttpRequest), keypair.name) \
- .AndRaise(self.exceptions.nova)
- self.mox.ReplayAll()
-
- context = {'keypair_name': keypair.name}
- url = reverse('horizon:project:access_and_security:keypairs:generate',
- kwargs={'keypair_name': keypair.name})
- res = self.client.get(url, context)
-
- self.assertRedirectsNoFollow(
- res, reverse('horizon:project:access_and_security:index'))
diff --git a/openstack_dashboard/dashboards/project/access_and_security/keypairs/urls.py b/openstack_dashboard/dashboards/project/access_and_security/keypairs/urls.py
deleted file mode 100644
index 429df16a..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/keypairs/urls.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.access_and_security.\
- keypairs.views import CreateView
-from openstack_dashboard.dashboards.project.access_and_security.\
- keypairs.views import DownloadView
-from openstack_dashboard.dashboards.project.access_and_security.\
- keypairs.views import GenerateView
-from openstack_dashboard.dashboards.project.access_and_security.\
- keypairs.views import ImportView
-
-
-urlpatterns = patterns('',
- url(r'^create/$', CreateView.as_view(), name='create'),
- url(r'^import/$', ImportView.as_view(), name='import'),
- url(r'^(?P<keypair_name>[^/]+)/download/$', DownloadView.as_view(),
- name='download'),
- url(r'^(?P<keypair_name>[^/]+)/generate/$', GenerateView.as_view(),
- name='generate'),
-)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/keypairs/views.py b/openstack_dashboard/dashboards/project/access_and_security/keypairs/views.py
deleted file mode 100644
index df5767f6..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/keypairs/views.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing keypairs.
-"""
-import logging
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django import http
-from django.template.defaultfilters import slugify
-from django.utils.translation import ugettext_lazy as _
-from django.views.generic import TemplateView
-from django.views.generic import View
-
-from horizon import exceptions
-from horizon import forms
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.project.access_and_security.\
- keypairs.forms import CreateKeypair
-from openstack_dashboard.dashboards.project.access_and_security.\
- keypairs.forms import ImportKeypair
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateKeypair
- template_name = 'project/access_and_security/keypairs/create.html'
- success_url = 'horizon:project:access_and_security:keypairs:download'
-
- def get_success_url(self):
- return reverse(self.success_url,
- kwargs={"keypair_name": self.request.POST['name']})
-
-
-class ImportView(forms.ModalFormView):
- form_class = ImportKeypair
- template_name = 'project/access_and_security/keypairs/import.html'
- success_url = reverse_lazy('horizon:project:access_and_security:index')
-
- def get_object_id(self, keypair):
- return keypair.name
-
-
-class DownloadView(TemplateView):
- def get_context_data(self, keypair_name=None):
- return {'keypair_name': keypair_name}
- template_name = 'project/access_and_security/keypairs/download.html'
-
-
-class GenerateView(View):
- def get(self, request, keypair_name=None):
- try:
- keypair = api.nova.keypair_create(request, keypair_name)
- except:
- redirect = reverse('horizon:project:access_and_security:index')
- exceptions.handle(self.request,
- _('Unable to create keypair: %(exc)s'),
- redirect=redirect)
-
- response = http.HttpResponse(mimetype='application/binary')
- response['Content-Disposition'] = \
- 'attachment; filename=%s.pem' % slugify(keypair.name)
- response.write(keypair.private_key)
- response['Content-Length'] = str(len(response.content))
- return response
diff --git a/openstack_dashboard/dashboards/project/access_and_security/panel.py b/openstack_dashboard/dashboards/project/access_and_security/panel.py
deleted file mode 100644
index 40831629..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/panel.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-# Copyright 2012 OpenStack LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.dashboards.project import dashboard
-
-
-class AccessAndSecurity(horizon.Panel):
- name = _("Access & Security")
- slug = 'access_and_security'
-
-
-dashboard.Project.register(AccessAndSecurity)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/security_groups/__init__.py b/openstack_dashboard/dashboards/project/access_and_security/security_groups/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/security_groups/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/access_and_security/security_groups/forms.py b/openstack_dashboard/dashboards/project/access_and_security/security_groups/forms.py
deleted file mode 100644
index 971d872f..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/security_groups/forms.py
+++ /dev/null
@@ -1,354 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-import netaddr
-
-from django.conf import settings
-from django.core.urlresolvers import reverse
-from django.core import validators
-from django.forms import ValidationError
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-from horizon.utils import fields
-from horizon.utils.validators import validate_ip_protocol
-from horizon.utils.validators import validate_port_range
-
-from openstack_dashboard import api
-from openstack_dashboard.utils.filters import get_int_or_uuid
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateGroup(forms.SelfHandlingForm):
- name = forms.CharField(label=_("Name"),
- error_messages={
- 'required': _('This field is required.'),
- 'invalid': _("The string may only contain"
- " ASCII characters and numbers.")},
- validators=[validators.validate_slug])
- description = forms.CharField(label=_("Description"))
-
- def handle(self, request, data):
- try:
- sg = api.network.security_group_create(request,
- data['name'],
- data['description'])
- messages.success(request,
- _('Successfully created security group: %s')
- % data['name'])
- return sg
- except:
- redirect = reverse("horizon:project:access_and_security:index")
- exceptions.handle(request,
- _('Unable to create security group.'),
- redirect=redirect)
-
-
-class AddRule(forms.SelfHandlingForm):
- id = forms.CharField(widget=forms.HiddenInput())
- rule_menu = forms.ChoiceField(label=_('Rule'),
- widget=forms.Select(attrs={
- 'class': 'switchable',
- 'data-slug': 'rule_menu'}))
-
- # "direction" field is enabled only when custom mode.
- # It is because most common rules in local_settings.py is meaningful
- # when its direction is 'ingress'.
- direction = forms.ChoiceField(
- label=_('Direction'),
- required=False,
- widget=forms.Select(attrs={
- 'class': 'switched',
- 'data-switch-on': 'rule_menu',
- 'data-rule_menu-tcp': _('Direction'),
- 'data-rule_menu-udp': _('Direction'),
- 'data-rule_menu-icmp': _('Direction'),
- 'data-rule_menu-custom': _('Direction'),
- 'data-rule_menu-all_tcp': _('Direction'),
- 'data-rule_menu-all_udp': _('Direction'),
- 'data-rule_menu-all_icmp': _('Direction'),
- }))
-
- ip_protocol = forms.IntegerField(
- label=_('IP Protocol'), required=False,
- help_text=_("Enter an integer value between 0 and 255 "
- "(or -1 which means wildcard)."),
- validators=[validate_ip_protocol],
- widget=forms.TextInput(attrs={
- 'class': 'switched',
- 'data-switch-on': 'rule_menu',
- 'data-rule_menu-custom': _('IP Protocol')}))
-
- port_or_range = forms.ChoiceField(
- label=_('Open Port'),
- choices=[('port', _('Port')),
- ('range', _('Port Range'))],
- widget=forms.Select(attrs={
- 'class': 'switchable switched',
- 'data-slug': 'range',
- 'data-switch-on': 'rule_menu',
- 'data-rule_menu-tcp': _('Open Port'),
- 'data-rule_menu-udp': _('Open Port')}))
-
- port = forms.IntegerField(label=_("Port"),
- required=False,
- help_text=_("Enter an integer value "
- "between 1 and 65535."),
- widget=forms.TextInput(attrs={
- 'class': 'switched',
- 'data-switch-on': 'range',
- 'data-range-port': _('Port')}),
- validators=[validate_port_range])
-
- from_port = forms.IntegerField(label=_("From Port"),
- required=False,
- help_text=_("Enter an integer value "
- "between 1 and 65535."),
- widget=forms.TextInput(attrs={
- 'class': 'switched',
- 'data-switch-on': 'range',
- 'data-range-range': _('From Port')}),
- validators=[validate_port_range])
-
- to_port = forms.IntegerField(label=_("To Port"),
- required=False,
- help_text=_("Enter an integer value "
- "between 1 and 65535."),
- widget=forms.TextInput(attrs={
- 'class': 'switched',
- 'data-switch-on': 'range',
- 'data-range-range': _('To Port')}),
- validators=[validate_port_range])
-
- icmp_type = forms.IntegerField(label=_("Type"),
- required=False,
- help_text=_("Enter a value for ICMP type "
- "in the range (-1: 255)"),
- widget=forms.TextInput(attrs={
- 'class': 'switched',
- 'data-switch-on': 'rule_menu',
- 'data-rule_menu-icmp': _('Type')}),
- validators=[validate_port_range])
-
- icmp_code = forms.IntegerField(label=_("Code"),
- required=False,
- help_text=_("Enter a value for ICMP code "
- "in the range (-1: 255)"),
- widget=forms.TextInput(attrs={
- 'class': 'switched',
- 'data-switch-on': 'rule_menu',
- 'data-rule_menu-icmp': _('Code')}),
- validators=[validate_port_range])
-
- remote = forms.ChoiceField(label=_('Remote'),
- choices=[('cidr', _('CIDR')),
- ('sg', _('Security Group'))],
- help_text=_('To specify an allowed IP '
- 'range, select "CIDR". To '
- 'allow access from all '
- 'members of another security '
- 'group select "Security '
- 'Group".'),
- widget=forms.Select(attrs={
- 'class': 'switchable',
- 'data-slug': 'remote'}))
-
- cidr = fields.IPField(label=_("CIDR"),
- required=False,
- initial="0.0.0.0/0",
- help_text=_("Classless Inter-Domain Routing "
- "(e.g. 192.168.0.0/24)"),
- version=fields.IPv4 | fields.IPv6,
- mask=True,
- widget=forms.TextInput(
- attrs={'class': 'switched',
- 'data-switch-on': 'remote',
- 'data-remote-cidr': _('CIDR')}))
-
- security_group = forms.ChoiceField(label=_('Security Group'),
- required=False,
- widget=forms.Select(attrs={
- 'class': 'switched',
- 'data-switch-on': 'remote',
- 'data-remote-sg': _('Security '
- 'Group')}))
- # When cidr is used ethertype is determined from IP version of cidr.
- # When source group, ethertype needs to be specified explicitly.
- ethertype = forms.ChoiceField(label=_('Ether Type'),
- required=False,
- choices=[('IPv4', _('IPv4')),
- ('IPv6', _('IPv6'))],
- widget=forms.Select(attrs={
- 'class': 'switched',
- 'data-slug': 'ethertype',
- 'data-switch-on': 'remote',
- 'data-remote-sg': _('Ether Type')}))
-
- def __init__(self, *args, **kwargs):
- sg_list = kwargs.pop('sg_list', [])
- super(AddRule, self).__init__(*args, **kwargs)
- # Determine if there are security groups available for the
- # remote group option; add the choices and enable the option if so.
- if sg_list:
- security_groups_choices = sg_list
- else:
- security_groups_choices = [("", _("No security groups available"))]
- self.fields['security_group'].choices = security_groups_choices
-
- backend = api.network.security_group_backend(self.request)
-
- rules_dict = getattr(settings, 'SECURITY_GROUP_RULES', [])
- common_rules = [(k, _(rules_dict[k]['name']))
- for k in rules_dict
- if rules_dict[k].get('backend', backend) == backend]
- common_rules.sort()
- custom_rules = [('tcp', _('Custom TCP Rule')),
- ('udp', _('Custom UDP Rule')),
- ('icmp', _('Custom ICMP Rule'))]
- if backend == 'neutron':
- custom_rules.append(('custom', _('Other Protocol')))
- self.fields['rule_menu'].choices = custom_rules + common_rules
- self.rules = rules_dict
-
- if backend == 'neutron':
- self.fields['direction'].choices = [('ingress', _('Ingress')),
- ('egress', _('Egress'))]
- else:
- # direction and ethertype are not supported in Nova secgroup.
- self.fields['direction'].widget = forms.HiddenInput()
- self.fields['ethertype'].widget = forms.HiddenInput()
- # ip_protocol field is to specify arbitrary protocol number
- # and it is available only for neutron security group.
- self.fields['ip_protocol'].widget = forms.HiddenInput()
-
- def clean(self):
- cleaned_data = super(AddRule, self).clean()
-
- rule_menu = cleaned_data.get('rule_menu')
- port_or_range = cleaned_data.get("port_or_range")
- remote = cleaned_data.get("remote")
-
- icmp_type = cleaned_data.get("icmp_type", None)
- icmp_code = cleaned_data.get("icmp_code", None)
-
- from_port = cleaned_data.get("from_port", None)
- to_port = cleaned_data.get("to_port", None)
- port = cleaned_data.get("port", None)
-
- if rule_menu == 'icmp':
- cleaned_data['ip_protocol'] = rule_menu
- if icmp_type is None:
- msg = _('The ICMP type is invalid.')
- raise ValidationError(msg)
- if icmp_code is None:
- msg = _('The ICMP code is invalid.')
- raise ValidationError(msg)
- if icmp_type not in xrange(-1, 256):
- msg = _('The ICMP type not in range (-1, 255)')
- raise ValidationError(msg)
- if icmp_code not in xrange(-1, 256):
- msg = _('The ICMP code not in range (-1, 255)')
- raise ValidationError(msg)
- cleaned_data['from_port'] = icmp_type
- cleaned_data['to_port'] = icmp_code
- elif rule_menu == 'tcp' or rule_menu == 'udp':
- cleaned_data['ip_protocol'] = rule_menu
- if port_or_range == "port":
- cleaned_data["from_port"] = port
- cleaned_data["to_port"] = port
- if port is None:
- msg = _('The specified port is invalid.')
- raise ValidationError(msg)
- else:
- if from_port is None:
- msg = _('The "from" port number is invalid.')
- raise ValidationError(msg)
- if to_port is None:
- msg = _('The "to" port number is invalid.')
- raise ValidationError(msg)
- if to_port < from_port:
- msg = _('The "to" port number must be greater than '
- 'or equal to the "from" port number.')
- raise ValidationError(msg)
- elif rule_menu == 'custom':
- pass
- else:
- cleaned_data['ip_protocol'] = self.rules[rule_menu]['ip_protocol']
- cleaned_data['from_port'] = int(self.rules[rule_menu]['from_port'])
- cleaned_data['to_port'] = int(self.rules[rule_menu]['to_port'])
- cleaned_data['direction'] = self.rules[rule_menu].get('direction')
-
- # NOTE(amotoki): There are two cases where cleaned_data['direction']
- # is empty: (1) Nova Security Group is used. Since "direction" is
- # HiddenInput, direction field exists but its value is ''.
- # (2) Template is used. In this case, the default value is None.
- # To make sure 'direction' field has 'ingress' or 'egress',
- # fill this field here if it is not specified.
- if not cleaned_data['direction']:
- cleaned_data['direction'] = 'ingress'
-
- if remote == "cidr":
- cleaned_data['security_group'] = None
- else:
- cleaned_data['cidr'] = None
-
- # If cleaned_data does not contain cidr, cidr is already marked
- # as invalid, so skip the further validation for cidr.
- # In addition cleaned_data['cidr'] is None means source_group is used.
- if 'cidr' in cleaned_data and cleaned_data['cidr'] is not None:
- cidr = cleaned_data['cidr']
- if not cidr:
- msg = _('CIDR must be specified.')
- self._errors['cidr'] = self.error_class([msg])
- else:
- # If cidr is specified, ethertype is determined from IP address
- # version. It is used only when Neutron is enabled.
- ip_ver = netaddr.IPNetwork(cidr).version
- cleaned_data['ethertype'] = 'IPv6' if ip_ver == 6 else 'IPv4'
-
- return cleaned_data
-
- def handle(self, request, data):
- try:
- rule = api.network.security_group_rule_create(
- request,
- get_int_or_uuid(data['id']),
- data['direction'],
- data['ethertype'],
- data['ip_protocol'],
- data['from_port'],
- data['to_port'],
- data['cidr'],
- data['security_group'])
- messages.success(request,
- _('Successfully added rule: %s') % unicode(rule))
- return rule
- except:
- redirect = reverse("horizon:project:access_and_security:"
- "security_groups:detail", args=[data['id']])
- exceptions.handle(request,
- _('Unable to add rule to security group.'),
- redirect=redirect)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/security_groups/tables.py b/openstack_dashboard/dashboards/project/access_and_security/security_groups/tables.py
deleted file mode 100644
index 33910277..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/security_groups/tables.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.conf import settings
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-from openstack_dashboard import api
-from openstack_dashboard.utils.filters import get_int_or_uuid
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DeleteGroup(tables.DeleteAction):
- data_type_singular = _("Security Group")
- data_type_plural = _("Security Groups")
-
- def allowed(self, request, security_group=None):
- if not security_group:
- return True
- return security_group.name != 'default'
-
- def delete(self, request, obj_id):
- api.network.security_group_delete(request, obj_id)
-
-
-class CreateGroup(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Security Group")
- url = "horizon:project:access_and_security:security_groups:create"
- classes = ("ajax-modal", "btn-create")
-
-
-class EditRules(tables.LinkAction):
- name = "edit_rules"
- verbose_name = _("Edit Rules")
- url = "horizon:project:access_and_security:security_groups:detail"
- classes = ("btn-edit")
-
-
-class SecurityGroupsTable(tables.DataTable):
- name = tables.Column("name", verbose_name=_("Name"))
- description = tables.Column("description", verbose_name=_("Description"))
-
- def sanitize_id(self, obj_id):
- return get_int_or_uuid(obj_id)
-
- class Meta:
- name = "security_groups"
- verbose_name = _("Security Groups")
- table_actions = (CreateGroup, DeleteGroup)
- row_actions = (EditRules, DeleteGroup)
-
-
-class CreateRule(tables.LinkAction):
- name = "add_rule"
- verbose_name = _("Add Rule")
- url = "horizon:project:access_and_security:security_groups:add_rule"
- classes = ("ajax-modal", "btn-create")
-
- def get_link_url(self):
- return reverse(self.url, args=[self.table.kwargs['security_group_id']])
-
-
-class DeleteRule(tables.DeleteAction):
- data_type_singular = _("Rule")
- data_type_plural = _("Rules")
-
- def delete(self, request, obj_id):
- api.network.security_group_rule_delete(request, obj_id)
-
- def get_success_url(self, request):
- sg_id = self.table.kwargs['security_group_id']
- return reverse("horizon:project:access_and_security:"
- "security_groups:detail", args=[sg_id])
-
-
-def get_remote(rule):
- if 'cidr' in rule.ip_range:
- if rule.ip_range['cidr'] is None:
- range = '::/0' if rule.ethertype == 'IPv6' else '0.0.0.0/0'
- else:
- range = rule.ip_range['cidr']
- return range + ' (CIDR)'
- elif 'name' in rule.group:
- return rule.group['name']
- else:
- return None
-
-
-def get_port_range(rule):
- ip_proto = rule.ip_protocol
- if rule.from_port == rule.to_port:
- return check_rule_template(rule.from_port, ip_proto)
- else:
- return (u"%(from)s - %(to)s" %
- {'from': check_rule_template(rule.from_port, ip_proto),
- 'to': check_rule_template(rule.to_port, ip_proto)})
-
-
-def filter_direction(direction):
- if direction is None or direction.lower() == 'ingress':
- return _('Ingress')
- else:
- return _('Egress')
-
-
-def filter_protocol(protocol):
- if protocol is None:
- return _('Any')
- return unicode.upper(protocol)
-
-
-def check_rule_template(port, ip_proto):
- rules_dict = getattr(settings, 'SECURITY_GROUP_RULES', {})
- if not rules_dict:
- return port
- templ_rule = filter(lambda rule: str(port) == rule['from_port']
- and str(port) == rule['to_port']
- and ip_proto == rule['ip_protocol'],
- [rule for rule in rules_dict.values()])
- if templ_rule:
- return u"%(from_port)s (%(name)s)" % templ_rule[0]
- return port
-
-
-class RulesTable(tables.DataTable):
- direction = tables.Column("direction",
- verbose_name=_("Direction"),
- filters=(filter_direction,))
- ethertype = tables.Column("ethertype",
- verbose_name=_("Ether Type"))
- protocol = tables.Column("ip_protocol",
- verbose_name=_("IP Protocol"),
- filters=(filter_protocol,))
- port_range = tables.Column(get_port_range,
- verbose_name=_("Port Range"))
- remote = tables.Column(get_remote, verbose_name=_("Remote"))
-
- def sanitize_id(self, obj_id):
- return get_int_or_uuid(obj_id)
-
- def get_object_display(self, rule):
- return unicode(rule)
-
- class Meta:
- name = "rules"
- verbose_name = _("Security Group Rules")
- table_actions = (CreateRule, DeleteRule)
- row_actions = (DeleteRule,)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/security_groups/tests.py b/openstack_dashboard/dashboards/project/access_and_security/security_groups/tests.py
deleted file mode 100644
index eb54079b..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/security_groups/tests.py
+++ /dev/null
@@ -1,664 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import cgi
-
-from django.conf import settings
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-from openstack_dashboard.dashboards.project.access_and_security.\
- security_groups.tables import RulesTable
-from openstack_dashboard.dashboards.project.access_and_security.\
- security_groups.tables import SecurityGroupsTable
-
-
-INDEX_URL = reverse('horizon:project:access_and_security:index')
-SG_CREATE_URL = reverse('horizon:project:access_and_security:'
- 'security_groups:create')
-
-
-def strip_absolute_base(uri):
- return uri.split(settings.TESTSERVER, 1)[-1]
-
-
-class SecurityGroupsViewTests(test.TestCase):
- secgroup_backend = 'nova'
-
- def setUp(self):
- super(SecurityGroupsViewTests, self).setUp()
- sec_group = self.security_groups.first()
- self.detail_url = reverse('horizon:project:access_and_security:'
- 'security_groups:detail',
- args=[sec_group.id])
- self.edit_url = reverse('horizon:project:access_and_security:'
- 'security_groups:add_rule',
- args=[sec_group.id])
-
- def test_create_security_groups_get(self):
- res = self.client.get(SG_CREATE_URL)
- self.assertTemplateUsed(res,
- 'project/access_and_security/security_groups/create.html')
-
- @test.create_stubs({api.network: ('security_group_create',)})
- def test_create_security_groups_post(self):
- sec_group = self.security_groups.first()
- api.network.security_group_create(IsA(http.HttpRequest),
- sec_group.name,
- sec_group.description) \
- .AndReturn(sec_group)
- self.mox.ReplayAll()
-
- formData = {'method': 'CreateGroup',
- 'name': sec_group.name,
- 'description': sec_group.description}
- res = self.client.post(SG_CREATE_URL, formData)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.network: ('security_group_create',)})
- def test_create_security_groups_post_exception(self):
- sec_group = self.security_groups.first()
- api.network.security_group_create(IsA(http.HttpRequest),
- sec_group.name,
- sec_group.description) \
- .AndRaise(self.exceptions.nova)
- self.mox.ReplayAll()
-
- formData = {'method': 'CreateGroup',
- 'name': sec_group.name,
- 'description': sec_group.description}
- res = self.client.post(SG_CREATE_URL, formData)
- self.assertMessageCount(error=1)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.network: ('security_group_create',)})
- def test_create_security_groups_post_wrong_name(self):
- sec_group = self.security_groups.first()
- fail_name = sec_group.name + ' invalid'
- self.mox.ReplayAll()
-
- formData = {'method': 'CreateGroup',
- 'name': fail_name,
- 'description': sec_group.description}
- res = self.client.post(SG_CREATE_URL, formData)
- self.assertTemplateUsed(res,
- 'project/access_and_security/security_groups/create.html')
- self.assertContains(res, "ASCII")
-
- @test.create_stubs({api.network: ('security_group_get',)})
- def test_detail_get(self):
- sec_group = self.security_groups.first()
-
- api.network.security_group_get(IsA(http.HttpRequest),
- sec_group.id).AndReturn(sec_group)
- self.mox.ReplayAll()
- res = self.client.get(self.detail_url)
- self.assertTemplateUsed(res,
- 'project/access_and_security/security_groups/detail.html')
-
- @test.create_stubs({api.network: ('security_group_get',)})
- def test_detail_get_exception(self):
- sec_group = self.security_groups.first()
-
- api.network.security_group_get(IsA(http.HttpRequest),
- sec_group.id) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- res = self.client.get(self.detail_url)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.network: ('security_group_rule_create',
- 'security_group_list',
- 'security_group_backend')})
- def test_detail_add_rule_cidr(self):
- sec_group = self.security_groups.first()
- sec_group_list = self.security_groups.list()
- rule = self.security_group_rules.first()
-
- api.network.security_group_backend(
- IsA(http.HttpRequest)).AndReturn(self.secgroup_backend)
- api.network.security_group_rule_create(IsA(http.HttpRequest),
- sec_group.id,
- 'ingress', 'IPv4',
- rule.ip_protocol,
- int(rule.from_port),
- int(rule.to_port),
- rule.ip_range['cidr'],
- None).AndReturn(rule)
- api.network.security_group_list(
- IsA(http.HttpRequest)).AndReturn(sec_group_list)
- self.mox.ReplayAll()
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'port_or_range': 'port',
- 'port': rule.from_port,
- 'rule_menu': rule.ip_protocol,
- 'cidr': rule.ip_range['cidr'],
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertRedirectsNoFollow(res, self.detail_url)
-
- @test.create_stubs({api.network: ('security_group_rule_create',
- 'security_group_list',
- 'security_group_backend')})
- def test_detail_add_rule_cidr_with_template(self):
- sec_group = self.security_groups.first()
- sec_group_list = self.security_groups.list()
- rule = self.security_group_rules.first()
-
- api.network.security_group_backend(
- IsA(http.HttpRequest)).AndReturn(self.secgroup_backend)
- api.network.security_group_rule_create(IsA(http.HttpRequest),
- sec_group.id,
- 'ingress', 'IPv4',
- rule.ip_protocol,
- int(rule.from_port),
- int(rule.to_port),
- rule.ip_range['cidr'],
- None).AndReturn(rule)
- api.network.security_group_list(
- IsA(http.HttpRequest)).AndReturn(sec_group_list)
- self.mox.ReplayAll()
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'rule_menu': 'http',
- 'port_or_range': 'port',
- 'cidr': rule.ip_range['cidr'],
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertRedirectsNoFollow(res, self.detail_url)
-
- def _get_source_group_rule(self):
- return self.security_group_rules.get(id=3)
-
- @test.create_stubs({api.network: ('security_group_rule_create',
- 'security_group_list',
- 'security_group_backend')})
- def test_detail_add_rule_self_as_source_group(self):
- sec_group = self.security_groups.first()
- sec_group_list = self.security_groups.list()
- rule = self._get_source_group_rule()
-
- api.network.security_group_backend(
- IsA(http.HttpRequest)).AndReturn(self.secgroup_backend)
- api.network.security_group_rule_create(
- IsA(http.HttpRequest),
- sec_group.id,
- 'ingress',
- # ethertype is empty for source_group of Nova Security Group
- '',
- rule.ip_protocol,
- int(rule.from_port),
- int(rule.to_port),
- None,
- u'%s' % sec_group.id).AndReturn(rule)
- api.network.security_group_list(
- IsA(http.HttpRequest)).AndReturn(sec_group_list)
- self.mox.ReplayAll()
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'port_or_range': 'port',
- 'port': rule.from_port,
- 'rule_menu': rule.ip_protocol,
- 'cidr': '0.0.0.0/0',
- 'security_group': sec_group.id,
- 'remote': 'sg'}
- res = self.client.post(self.edit_url, formData)
- self.assertRedirectsNoFollow(res, self.detail_url)
-
- @test.create_stubs({api.network: ('security_group_rule_create',
- 'security_group_list',
- 'security_group_backend')})
- def test_detail_add_rule_self_as_source_group_with_template(self):
- sec_group = self.security_groups.first()
- sec_group_list = self.security_groups.list()
- rule = self._get_source_group_rule()
-
- api.network.security_group_backend(
- IsA(http.HttpRequest)).AndReturn(self.secgroup_backend)
- api.network.security_group_rule_create(
- IsA(http.HttpRequest),
- sec_group.id,
- 'ingress',
- # ethertype is empty for source_group of Nova Security Group
- '',
- rule.ip_protocol,
- int(rule.from_port),
- int(rule.to_port),
- None,
- u'%s' % sec_group.id).AndReturn(rule)
- api.network.security_group_list(
- IsA(http.HttpRequest)).AndReturn(sec_group_list)
- self.mox.ReplayAll()
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'rule_menu': 'http',
- 'port_or_range': 'port',
- 'cidr': '0.0.0.0/0',
- 'security_group': sec_group.id,
- 'remote': 'sg'}
- res = self.client.post(self.edit_url, formData)
- self.assertRedirectsNoFollow(res, self.detail_url)
-
- @test.create_stubs({api.network: ('security_group_list',
- 'security_group_backend')})
- def test_detail_invalid_port(self):
- sec_group = self.security_groups.first()
- sec_group_list = self.security_groups.list()
- rule = self.security_group_rules.first()
-
- api.network.security_group_backend(
- IsA(http.HttpRequest)).AndReturn(self.secgroup_backend)
- api.network.security_group_list(
- IsA(http.HttpRequest)).AndReturn(sec_group_list)
- self.mox.ReplayAll()
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'port_or_range': 'port',
- 'port': None,
- 'rule_menu': rule.ip_protocol,
- 'cidr': rule.ip_range['cidr'],
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertNoMessages()
- self.assertContains(res, "The specified port is invalid")
-
- @test.create_stubs({api.network: ('security_group_list',
- 'security_group_backend')})
- def test_detail_invalid_port_range(self):
- sec_group = self.security_groups.first()
- sec_group_list = self.security_groups.list()
- rule = self.security_group_rules.first()
-
- for i in range(3):
- api.network.security_group_backend(
- IsA(http.HttpRequest)).AndReturn(self.secgroup_backend)
- api.network.security_group_list(
- IsA(http.HttpRequest)).AndReturn(sec_group_list)
- self.mox.ReplayAll()
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'port_or_range': 'range',
- 'from_port': rule.from_port,
- 'to_port': int(rule.from_port) - 1,
- 'rule_menu': rule.ip_protocol,
- 'cidr': rule.ip_range['cidr'],
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertNoMessages()
- self.assertContains(res, "greater than or equal to")
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'port_or_range': 'range',
- 'from_port': None,
- 'to_port': rule.to_port,
- 'rule_menu': rule.ip_protocol,
- 'cidr': rule.ip_range['cidr'],
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertNoMessages()
- self.assertContains(res, cgi.escape('"from" port number is invalid',
- quote=True))
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'port_or_range': 'range',
- 'from_port': rule.from_port,
- 'to_port': None,
- 'rule_menu': rule.ip_protocol,
- 'cidr': rule.ip_range['cidr'],
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertNoMessages()
- self.assertContains(res, cgi.escape('"to" port number is invalid',
- quote=True))
-
- @test.create_stubs({api.network: ('security_group_get',
- 'security_group_list',
- 'security_group_backend')})
- def test_detail_invalid_icmp_rule(self):
- sec_group = self.security_groups.first()
- sec_group_list = self.security_groups.list()
- icmp_rule = self.security_group_rules.list()[1]
-
- # Call POST 4 times
- for i in range(4):
- api.network.security_group_backend(
- IsA(http.HttpRequest)).AndReturn(self.secgroup_backend)
- api.network.security_group_list(
- IsA(http.HttpRequest)).AndReturn(sec_group_list)
-
- self.mox.ReplayAll()
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'port_or_range': 'port',
- 'icmp_type': 256,
- 'icmp_code': icmp_rule.to_port,
- 'rule_menu': icmp_rule.ip_protocol,
- 'cidr': icmp_rule.ip_range['cidr'],
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertNoMessages()
- self.assertContains(res, "The ICMP type not in range (-1, 255)")
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'port_or_range': 'port',
- 'icmp_type': icmp_rule.from_port,
- 'icmp_code': 256,
- 'rule_menu': icmp_rule.ip_protocol,
- 'cidr': icmp_rule.ip_range['cidr'],
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertNoMessages()
- self.assertContains(res, "The ICMP code not in range (-1, 255)")
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'port_or_range': 'port',
- 'icmp_type': icmp_rule.from_port,
- 'icmp_code': None,
- 'rule_menu': icmp_rule.ip_protocol,
- 'cidr': icmp_rule.ip_range['cidr'],
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertNoMessages()
- self.assertContains(res, "The ICMP code is invalid")
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'port_or_range': 'port',
- 'icmp_type': None,
- 'icmp_code': icmp_rule.to_port,
- 'rule_menu': icmp_rule.ip_protocol,
- 'cidr': icmp_rule.ip_range['cidr'],
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertNoMessages()
- self.assertContains(res, "The ICMP type is invalid")
-
- @test.create_stubs({api.network: ('security_group_rule_create',
- 'security_group_list',
- 'security_group_backend')})
- def test_detail_add_rule_exception(self):
- sec_group = self.security_groups.first()
- sec_group_list = self.security_groups.list()
- rule = self.security_group_rules.first()
-
- api.network.security_group_backend(
- IsA(http.HttpRequest)).AndReturn(self.secgroup_backend)
- api.network.security_group_rule_create(
- IsA(http.HttpRequest),
- sec_group.id, 'ingress', 'IPv4',
- rule.ip_protocol,
- int(rule.from_port),
- int(rule.to_port),
- rule.ip_range['cidr'],
- None).AndRaise(self.exceptions.nova)
- api.network.security_group_list(
- IsA(http.HttpRequest)).AndReturn(sec_group_list)
- self.mox.ReplayAll()
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'port_or_range': 'port',
- 'port': rule.from_port,
- 'rule_menu': rule.ip_protocol,
- 'cidr': rule.ip_range['cidr'],
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertRedirectsNoFollow(res, self.detail_url)
-
- @test.create_stubs({api.network: ('security_group_rule_delete',)})
- def test_detail_delete_rule(self):
- sec_group = self.security_groups.first()
- rule = self.security_group_rules.first()
-
- api.network.security_group_rule_delete(IsA(http.HttpRequest), rule.id)
- self.mox.ReplayAll()
-
- form_data = {"action": "rules__delete__%s" % rule.id}
- req = self.factory.post(self.edit_url, form_data)
- kwargs = {'security_group_id': sec_group.id}
- table = RulesTable(req, sec_group.rules, **kwargs)
- handled = table.maybe_handle()
- self.assertEqual(strip_absolute_base(handled['location']),
- self.detail_url)
-
- @test.create_stubs({api.network: ('security_group_rule_delete',)})
- def test_detail_delete_rule_exception(self):
- sec_group = self.security_groups.first()
- rule = self.security_group_rules.first()
-
- api.network.security_group_rule_delete(
- IsA(http.HttpRequest),
- rule.id).AndRaise(self.exceptions.nova)
- self.mox.ReplayAll()
-
- form_data = {"action": "rules__delete__%s" % rule.id}
- req = self.factory.post(self.edit_url, form_data)
- kwargs = {'security_group_id': sec_group.id}
- table = RulesTable(req, self.security_group_rules.list(), **kwargs)
- handled = table.maybe_handle()
- self.assertEqual(strip_absolute_base(handled['location']),
- self.detail_url)
-
- @test.create_stubs({api.network: ('security_group_delete',)})
- def test_delete_group(self):
- sec_group = self.security_groups.get(name="other_group")
-
- api.network.security_group_delete(IsA(http.HttpRequest), sec_group.id)
- self.mox.ReplayAll()
-
- form_data = {"action": "security_groups__delete__%s" % sec_group.id}
- req = self.factory.post(INDEX_URL, form_data)
- table = SecurityGroupsTable(req, self.security_groups.list())
- handled = table.maybe_handle()
- self.assertEqual(strip_absolute_base(handled['location']),
- INDEX_URL)
-
- @test.create_stubs({api.network: ('security_group_delete',)})
- def test_delete_group_exception(self):
- sec_group = self.security_groups.get(name="other_group")
-
- api.network.security_group_delete(
- IsA(http.HttpRequest),
- sec_group.id).AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- form_data = {"action": "security_groups__delete__%s" % sec_group.id}
- req = self.factory.post(INDEX_URL, form_data)
- table = SecurityGroupsTable(req, self.security_groups.list())
- handled = table.maybe_handle()
-
- self.assertEqual(strip_absolute_base(handled['location']),
- INDEX_URL)
-
-
-class SecurityGroupsNovaNeutronDriverTests(SecurityGroupsViewTests):
- secgroup_backend = 'nova'
-
- def setUp(self):
- super(SecurityGroupsNovaNeutronDriverTests, self).setUp()
-
- self._sec_groups_orig = self.security_groups
- self.security_groups = self.security_groups_uuid
-
- self._sec_group_rules_orig = self.security_group_rules
- self.security_group_rules = self.security_group_rules_uuid
-
- sec_group = self.security_groups.first()
- self.detail_url = reverse('horizon:project:access_and_security:'
- 'security_groups:detail',
- args=[sec_group.id])
- self.edit_url = reverse('horizon:project:access_and_security:'
- 'security_groups:add_rule',
- args=[sec_group.id])
-
- def tearDown(self):
- self.security_groups = self._sec_groups_orig
- self.security_group_rules = self._sec_group_rules_orig
- super(SecurityGroupsNovaNeutronDriverTests, self).tearDown()
-
-
-class SecurityGroupsNeutronTests(SecurityGroupsViewTests):
- secgroup_backend = 'neutron'
-
- def setUp(self):
- super(SecurityGroupsNeutronTests, self).setUp()
-
- self._sec_groups_orig = self.security_groups
- self.security_groups = self.q_secgroups
-
- self._sec_group_rules_orig = self.security_group_rules
- self.security_group_rules = self.q_secgroup_rules
-
- sec_group = self.security_groups.first()
- self.detail_url = reverse('horizon:project:access_and_security:'
- 'security_groups:detail',
- args=[sec_group.id])
- self.edit_url = reverse('horizon:project:access_and_security:'
- 'security_groups:add_rule',
- args=[sec_group.id])
-
- def tearDown(self):
- self.security_groups = self._sec_groups_orig
- self.security_group_rules = self._sec_group_rules_orig
- super(SecurityGroupsNeutronTests, self).tearDown()
-
- def _get_source_group_rule(self):
- for rule in self.security_group_rules.list():
- if rule.group:
- return rule
- raise Exception("No matches found.")
-
- # Additional tests for Neutron Security Group original features
-
- @test.create_stubs({api.network: ('security_group_rule_create',
- 'security_group_list',
- 'security_group_backend')})
- def test_detail_add_rule_custom_protocol(self):
- sec_group = self.security_groups.first()
- sec_group_list = self.security_groups.list()
- rule = self.security_group_rules.first()
-
- api.network.security_group_backend(
- IsA(http.HttpRequest)).AndReturn(self.secgroup_backend)
- api.network.security_group_rule_create(IsA(http.HttpRequest),
- sec_group.id, 'ingress', 'IPv6',
- 37, None, None, 'fe80::/48',
- None).AndReturn(rule)
- api.network.security_group_list(
- IsA(http.HttpRequest)).AndReturn(sec_group_list)
- self.mox.ReplayAll()
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'rule_menu': 'custom',
- 'direction': 'ingress',
- 'port_or_range': 'port',
- 'ip_protocol': 37,
- 'cidr': 'fe80::/48',
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertRedirectsNoFollow(res, self.detail_url)
-
- @test.create_stubs({api.network: ('security_group_rule_create',
- 'security_group_list',
- 'security_group_backend')})
- def test_detail_add_rule_egress(self):
- sec_group = self.security_groups.first()
- sec_group_list = self.security_groups.list()
- rule = self.security_group_rules.first()
-
- api.network.security_group_backend(
- IsA(http.HttpRequest)).AndReturn(self.secgroup_backend)
- api.network.security_group_rule_create(IsA(http.HttpRequest),
- sec_group.id, 'egress', 'IPv4',
- 'udp', 80, 80, '10.1.1.0/24',
- None).AndReturn(rule)
- api.network.security_group_list(
- IsA(http.HttpRequest)).AndReturn(sec_group_list)
- self.mox.ReplayAll()
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'direction': 'egress',
- 'rule_menu': 'udp',
- 'port_or_range': 'port',
- 'port': 80,
- 'cidr': '10.1.1.0/24',
- 'remote': 'cidr'}
- res = self.client.post(self.edit_url, formData)
- self.assertRedirectsNoFollow(res, self.detail_url)
-
- @test.create_stubs({api.network: ('security_group_rule_create',
- 'security_group_list',
- 'security_group_backend')})
- def test_detail_add_rule_source_group_with_direction_ethertype(self):
- sec_group = self.security_groups.first()
- sec_group_list = self.security_groups.list()
- rule = self._get_source_group_rule()
-
- api.network.security_group_backend(
- IsA(http.HttpRequest)).AndReturn(self.secgroup_backend)
- api.network.security_group_rule_create(
- IsA(http.HttpRequest),
- sec_group.id,
- 'egress',
- # ethertype is empty for source_group of Nova Security Group
- 'IPv6',
- rule.ip_protocol,
- int(rule.from_port),
- int(rule.to_port),
- None,
- u'%s' % sec_group.id).AndReturn(rule)
- api.network.security_group_list(
- IsA(http.HttpRequest)).AndReturn(sec_group_list)
- self.mox.ReplayAll()
-
- formData = {'method': 'AddRule',
- 'id': sec_group.id,
- 'direction': 'egress',
- 'port_or_range': 'port',
- 'port': rule.from_port,
- 'rule_menu': rule.ip_protocol,
- 'cidr': '0.0.0.0/0',
- 'security_group': sec_group.id,
- 'remote': 'sg',
- 'ethertype': 'IPv6'}
- res = self.client.post(self.edit_url, formData)
- self.assertRedirectsNoFollow(res, self.detail_url)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/security_groups/urls.py b/openstack_dashboard/dashboards/project/access_and_security/security_groups/urls.py
deleted file mode 100644
index e1af21fb..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/security_groups/urls.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.access_and_security.\
- security_groups.views import AddRuleView
-from openstack_dashboard.dashboards.project.access_and_security.\
- security_groups.views import CreateView
-from openstack_dashboard.dashboards.project.access_and_security.\
- security_groups.views import DetailView
-
-
-urlpatterns = patterns('',
- url(r'^create/$', CreateView.as_view(), name='create'),
- url(r'^(?P<security_group_id>[^/]+)/$',
- DetailView.as_view(),
- name='detail'),
- url(r'^(?P<security_group_id>[^/]+)/add_rule/$',
- AddRuleView.as_view(),
- name='add_rule')
-)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/security_groups/views.py b/openstack_dashboard/dashboards/project/access_and_security/security_groups/views.py
deleted file mode 100644
index ca834bcc..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/security_groups/views.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing instances.
-"""
-import logging
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-
-from openstack_dashboard import api
-from openstack_dashboard.utils.filters import get_int_or_uuid
-
-from openstack_dashboard.dashboards.project.access_and_security.\
- security_groups.forms import AddRule
-from openstack_dashboard.dashboards.project.access_and_security.\
- security_groups.forms import CreateGroup
-from openstack_dashboard.dashboards.project.access_and_security.\
- security_groups.tables import RulesTable
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DetailView(tables.DataTableView):
- table_class = RulesTable
- template_name = 'project/access_and_security/security_groups/detail.html'
-
- def _get_data(self):
- if not hasattr(self, '_sg'):
- sg_id = get_int_or_uuid(self.kwargs['security_group_id'])
- try:
- self._sg = api.network.security_group_get(self.request, sg_id)
- except:
- redirect = reverse('horizon:project:access_and_security:index')
- exceptions.handle(self.request,
- _('Unable to retrieve security group.'),
- redirect=redirect)
- return self._sg
-
- def get_data(self):
- return self._get_data().rules
-
- def get_context_data(self, **kwargs):
- context = super(DetailView, self).get_context_data(**kwargs)
- context["security_group"] = self._get_data()
- return context
-
-
-class AddRuleView(forms.ModalFormView):
- form_class = AddRule
- template_name = 'project/access_and_security/security_groups/add_rule.html'
-
- def get_success_url(self):
- sg_id = self.kwargs['security_group_id']
- return reverse("horizon:project:access_and_security:"
- "security_groups:detail", args=[sg_id])
-
- def get_context_data(self, **kwargs):
- context = super(AddRuleView, self).get_context_data(**kwargs)
- context["security_group_id"] = self.kwargs['security_group_id']
- return context
-
- def get_initial(self):
- return {'id': self.kwargs['security_group_id']}
-
- def get_form_kwargs(self):
- kwargs = super(AddRuleView, self).get_form_kwargs()
-
- try:
- groups = api.network.security_group_list(self.request)
- except:
- groups = []
- exceptions.handle(self.request,
- _("Unable to retrieve security groups."))
-
- security_groups = []
- for group in groups:
- if group.id == get_int_or_uuid(self.kwargs['security_group_id']):
- security_groups.append((group.id,
- _("%s (current)") % group.name))
- else:
- security_groups.append((group.id, group.name))
- kwargs['sg_list'] = security_groups
- return kwargs
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateGroup
- template_name = 'project/access_and_security/security_groups/create.html'
- success_url = reverse_lazy('horizon:project:access_and_security:index')
diff --git a/openstack_dashboard/dashboards/project/access_and_security/tabs.py b/openstack_dashboard/dashboards/project/access_and_security/tabs.py
deleted file mode 100644
index 077df934..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/tabs.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-# Copyright 2012 OpenStack LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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 _
-
-from horizon import exceptions
-from horizon import messages
-from horizon import tabs
-
-from openstack_dashboard.api import keystone
-from openstack_dashboard.api import network
-from openstack_dashboard.api import nova
-
-from openstack_dashboard.dashboards.project.access_and_security.\
- api_access.tables import EndpointsTable
-from openstack_dashboard.dashboards.project.access_and_security.\
- floating_ips.tables import FloatingIPsTable
-from openstack_dashboard.dashboards.project.access_and_security.\
- keypairs.tables import KeypairsTable
-from openstack_dashboard.dashboards.project.access_and_security.\
- security_groups.tables import SecurityGroupsTable
-
-
-class SecurityGroupsTab(tabs.TableTab):
- table_classes = (SecurityGroupsTable,)
- name = _("Security Groups")
- slug = "security_groups_tab"
- template_name = "horizon/common/_detail_table.html"
-
- def get_security_groups_data(self):
- try:
- security_groups = network.security_group_list(self.request)
- except:
- security_groups = []
- exceptions.handle(self.request,
- _('Unable to retrieve security groups.'))
- return security_groups
-
-
-class KeypairsTab(tabs.TableTab):
- table_classes = (KeypairsTable,)
- name = _("Keypairs")
- slug = "keypairs_tab"
- template_name = "horizon/common/_detail_table.html"
-
- def get_keypairs_data(self):
- try:
- keypairs = nova.keypair_list(self.request)
- except:
- keypairs = []
- exceptions.handle(self.request,
- _('Unable to retrieve keypair list.'))
- return keypairs
-
-
-class FloatingIPsTab(tabs.TableTab):
- table_classes = (FloatingIPsTable,)
- name = _("Floating IPs")
- slug = "floating_ips_tab"
- template_name = "horizon/common/_detail_table.html"
-
- def get_floating_ips_data(self):
- try:
- floating_ips = network.tenant_floating_ip_list(self.request)
- except:
- floating_ips = []
- exceptions.handle(self.request,
- _('Unable to retrieve floating IP addresses.'))
-
- try:
- floating_ip_pools = network.floating_ip_pools_list(self.request)
- except:
- floating_ip_pools = []
- messages.warning(self.request,
- _('Unable to retrieve floating IP pools.'))
- pool_dict = dict([(obj.id, obj.name) for obj in floating_ip_pools])
-
- instances = []
- try:
- instances, has_more = nova.server_list(self.request)
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve instance list.'))
-
- instances_dict = dict([(obj.id, obj) for obj in instances])
-
- for ip in floating_ips:
- ip.instance_name = instances_dict[ip.instance_id].name \
- if ip.instance_id in instances_dict else None
- ip.pool_name = pool_dict.get(ip.pool, ip.pool)
-
- return floating_ips
-
-
-class APIAccessTab(tabs.TableTab):
- table_classes = (EndpointsTable,)
- name = _("API Access")
- slug = "api_access_tab"
- template_name = "horizon/common/_detail_table.html"
-
- def get_endpoints_data(self):
- services = []
- for i, service in enumerate(self.request.user.service_catalog):
- service['id'] = i
- services.append(
- keystone.Service(service, self.request.user.services_region))
-
- return services
-
-
-class AccessAndSecurityTabs(tabs.TabGroup):
- slug = "access_security_tabs"
- tabs = (SecurityGroupsTab, KeypairsTab, FloatingIPsTab, APIAccessTab)
- sticky = True
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/ec2rc.sh.template b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/ec2rc.sh.template
deleted file mode 100644
index 0b6f7e27..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/ec2rc.sh.template
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-NOVARC=$(readlink -f "${BASH_SOURCE:-${0}}" 2>/dev/null) || NOVARC=$(python -c 'import os,sys; print os.path.abspath(os.path.realpath(sys.argv[1]))' "${BASH_SOURCE:-${0}}")
-NOVA_KEY_DIR=${NOVARC%/*}
-export EC2_ACCESS_KEY={{ ec2_access_key }}
-export EC2_SECRET_KEY={{ ec2_secret_key }}
-export EC2_URL={{ ec2_endpoint }}
-export EC2_USER_ID=42 # nova does not use user id, but bundling requires it
-export EC2_PRIVATE_KEY=${NOVA_KEY_DIR}/pk.pem
-export EC2_CERT=${NOVA_KEY_DIR}/cert.pem
-export NOVA_CERT=${NOVA_KEY_DIR}/cacert.pem
-export EUCALYPTUS_CERT=${NOVA_CERT} # euca-bundle-image seems to require this set
-{% if s3_endpoint %}export S3_URL={{ s3_endpoint }}{% endif %}
-alias ec2-bundle-image="ec2-bundle-image --cert ${EC2_CERT} --privatekey ${EC2_PRIVATE_KEY} --user 42 --ec2cert ${NOVA_CERT}"
-alias ec2-upload-bundle="ec2-upload-bundle -a ${EC2_ACCESS_KEY} -s ${EC2_SECRET_KEY} --url ${S3_URL} --ec2cert ${NOVA_CERT}"
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/openrc.sh.template b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/openrc.sh.template
deleted file mode 100644
index d1733eb7..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/api_access/openrc.sh.template
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-# With the addition of Keystone, to use an openstack cloud you should
-# authenticate against keystone, which returns a **Token** and **Service
-# Catalog**. The catalog contains the endpoint for all services the
-# user/tenant has access to - including nova, glance, keystone, swift.
-#
-# *NOTE*: Using the 2.0 *auth api* does not mean that compute api is 2.0. We
-# will use the 1.1 *compute api*
-export OS_AUTH_URL={{ auth_url }}
-
-# With the addition of Keystone we have standardized on the term **tenant**
-# as the entity that owns the resources.
-export OS_TENANT_ID={{ tenant_id }}
-export OS_TENANT_NAME="{{ tenant_name }}"
-
-# In addition to the owning entity (tenant), openstack stores the entity
-# performing the action as the **user**.
-export OS_USERNAME={{ user.username }}
-
-# With Keystone you pass the keystone password.
-echo "Please enter your OpenStack Password: "
-read -s OS_PASSWORD_INPUT
-export OS_PASSWORD=$OS_PASSWORD_INPUT
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html
deleted file mode 100644
index b8d9d4fd..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html
+++ /dev/null
@@ -1,44 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-
-{% load horizon i18n %}
-{% load url from future %}
-
-{% block form_id %}associate_floating_ip_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:access_and_security:floating_ips:allocate' %}{% endblock %}
-
-{% block modal-header %}{% trans "Allocate Floating IP" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right quota-dynamic">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "Allocate a floating IP from a given floating IP pool." %}</p>
-
- <h3>{% trans "Project Quotas" %}</h3>
- <div class="quota_title">
- <strong>{% trans "Floating IP" %} <span>({{ usages.floating_ips.used }})</span></strong>
- <p>{{ usages.floating_ips.available|quota }}</p>
- </div>
- <div class="clearfix"></div>
- <div id="floating_ip_progress" class="quota_bar" data-quota-used="{{ usages.floating_ips.used }}" data-quota-limit="{{ usages.floating_ips.quota }}" data-progress-indicator-step-by="1"></div>
-</div>
-
- <script type="text/javascript" charset="utf-8">
- if(typeof horizon.Quota !== 'undefined') {
- horizon.Quota.init();
- } else {
- addHorizonLoadEvent(function() {
- horizon.Quota.init();
- });
- }
- </script>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right {% if usages.floating_ips.used >= usages.floating_ips.quota %}disabled" type="button"{% else %}" type="submit"{% endif %} value="{% trans "Allocate IP" %}" />
- <a href="{% url 'horizon:project:access_and_security:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html
deleted file mode 100644
index 8679b9e8..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Allocate Floating IP" %}{% endblock %}
-
-{% block main %}
- {% include 'project/access_and_security/floating_ips/_allocate.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/index.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/index.html
deleted file mode 100644
index 7a00d8db..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/index.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Access &amp; Security" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Access &amp; Security") %}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html
deleted file mode 100644
index 69b32163..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_keypair_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:access_and_security:keypairs:create' %}{% endblock %}
-
-{% block modal-header %}{% trans "Create Keypair" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "Keypairs are ssh credentials which are injected into images when they are launched. Creating a new key pair registers the public key and downloads the private key (a .pem file)." %}</p>
- <p>{% trans "Protect and use the key as you would any normal ssh private key." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Keypair" %}" />
- <a href="{% url 'horizon:project:access_and_security:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html
deleted file mode 100644
index ffac373c..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}import_keypair_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:access_and_security:keypairs:import' %}{% endblock %}
-
-{% block modal-header %}{% trans "Import Keypair" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "Keypairs are ssh credentials which are injected into images when they are launched. Creating a new key pair registers the public key and downloads the private key (a .pem file)." %}</p>
- <p>{% trans "Protect and use the key as you would any normal ssh private key." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Import Keypair" %}" />
- <a href="{% url 'horizon:project:access_and_security:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html
deleted file mode 100644
index 5bd1fc48..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Keypair" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create Keypair") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/access_and_security/keypairs/_create.html' %}
-{% endblock %}
-
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html
deleted file mode 100644
index d2fe568b..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% load url from future %}
-{% block title %}{% blocktrans %}Download Keypair{% endblocktrans %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Download Keypair") %}
-{% endblock page_header %}
-
-{% block main %}
- <div class="modal-header">
- <h3>{% blocktrans %}The keypair &quot;{{ keypair_name }}&quot; should download automatically. If not use the link below.{% endblocktrans %}</h3>
- </div>
- <div class="modal-body clearfix">
- <a href="{% url 'horizon:project:access_and_security:keypairs:generate' keypair_name %}">
- {% blocktrans %}Download keypair &quot;{{ keypair_name}}&quot;{% endblocktrans %}
- </a>
- </div>
- <script type="text/javascript" charset="utf-8">
- document.location = '{% url 'horizon:project:access_and_security:keypairs:generate' keypair_name %}';
- </script>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html
deleted file mode 100644
index 5ba01e98..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Import Keypair" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Import Keypair") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/access_and_security/keypairs/_import.html' %}
-{% endblock %}
-
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html
deleted file mode 100644
index 4f47dbe7..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_security_group_rule_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:access_and_security:security_groups:add_rule' security_group_id %}{% endblock %}
-
-{% block modal-header %}{% trans "Add Rule" %}{% endblock %}
-{% block modal_id %}create_security_group_rule_modal{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% blocktrans %}Rules define which traffic is allowed to instances assigned to the security group. A security group rule consists of three main parts:{% endblocktrans %}</p>
- <p><strong>{% trans "Rule" %}</strong>: {% blocktrans %}You can specify the desired rule template or use custom rules, the options are Custom TCP Rule, Custom UDP Rule, or Custom ICMP Rule.{% endblocktrans %}</p>
- <p><strong>{% trans "Open Port/Port Range" %}</strong>: {% blocktrans %}For TCP and UDP rules you may choose to open either a single port or a range of ports. Selecting the "Port Range" option will provide you with space to provide both the starting and ending ports for the range. For ICMP rules you instead specify an ICMP type and code in the spaces provided.{% endblocktrans %}</p>
- <p><strong>{% trans "Remote" %}</strong>: {% blocktrans %}You must specify the source of the traffic to be allowed via this rule. You may do so either in the form of an IP address block (CIDR) or via a source group (Security Group). Selecting a security group as the source will allow any other instance in that security group access to any other instance via this rule.{% endblocktrans %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Add" %}" />
- <a href="{% url 'horizon:project:access_and_security:security_groups:detail' security_group_id %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html
deleted file mode 100644
index b2f8d63d..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_security_group_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:access_and_security:security_groups:create' %}{% endblock %}
-
-{% block modal-header %}{% trans "Create Security Group" %}{% endblock %}
-{% block modal_id %}create_security_group_modal{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "From here you can create a new security group" %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Security Group" %}" />
- <a href="{% url 'horizon:project:access_and_security:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html
deleted file mode 100644
index eee0b337..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Add Rule" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Add Rule") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/access_and_security/security_groups/_add_rule.html' %}
-{% endblock %}
-
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html
deleted file mode 100644
index 58c2b8bd..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Security Group" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create Security Group") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/access_and_security/security_groups/_create.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html b/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html
deleted file mode 100644
index 66c9b476..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Edit Security Group Rules" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Edit Security Group Rules: ")|add:security_group.name %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/access_and_security/tests.py b/openstack_dashboard/dashboards/project/access_and_security/tests.py
deleted file mode 100644
index 5f2ec562..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/tests.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from copy import deepcopy
-
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from horizon.workflows.views import WorkflowView
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class AccessAndSecurityTests(test.TestCase):
- def setUp(self):
- super(AccessAndSecurityTests, self).setUp()
-
- def test_index(self):
- keypairs = self.keypairs.list()
- sec_groups = self.security_groups.list()
- floating_ips = self.floating_ips.list()
- self.mox.StubOutWithMock(api.network, 'tenant_floating_ip_list')
- self.mox.StubOutWithMock(api.network, 'security_group_list')
- self.mox.StubOutWithMock(api.nova, 'keypair_list')
- self.mox.StubOutWithMock(api.nova, 'server_list')
-
- api.nova.server_list(IsA(http.HttpRequest)) \
- .AndReturn([self.servers.list(), False])
- api.nova.keypair_list(IsA(http.HttpRequest)).AndReturn(keypairs)
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn(floating_ips)
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(sec_groups)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:access_and_security:index')
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, 'project/access_and_security/index.html')
- self.assertItemsEqual(res.context['keypairs_table'].data, keypairs)
- self.assertItemsEqual(res.context['security_groups_table'].data,
- sec_groups)
- self.assertItemsEqual(res.context['floating_ips_table'].data,
- floating_ips)
-
- def test_association(self):
- servers = [api.nova.Server(s, self.request)
- for s in self.servers.list()]
- # Add duplicate instance name to test instance name with [ID]
- # Change id and private IP
- server3 = api.nova.Server(self.servers.first(), self.request)
- server3.id = 101
- server3.addresses = deepcopy(server3.addresses)
- server3.addresses['private'][0]['addr'] = "10.0.0.5"
- servers.append(server3)
-
- targets = [api.nova.FloatingIpTarget(s) for s in servers]
-
- self.mox.StubOutWithMock(api.network, 'tenant_floating_ip_list')
- self.mox.StubOutWithMock(api.network, 'floating_ip_target_list')
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn(self.floating_ips.list())
- api.network.floating_ip_target_list(IsA(http.HttpRequest)) \
- .AndReturn(targets)
- self.mox.ReplayAll()
-
- res = self.client.get(reverse("horizon:project:access_and_security:"
- "floating_ips:associate"))
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- self.assertContains(res,
- '<option value="1">server_1 (1)</option>')
- self.assertContains(res,
- '<option value="101">server_1 (101)</option>')
- self.assertContains(res, '<option value="2">server_2 (2)</option>')
-
-
-class AccessAndSecurityNeutronProxyTests(AccessAndSecurityTests):
- def setUp(self):
- super(AccessAndSecurityNeutronProxyTests, self).setUp()
- self.floating_ips = self.floating_ips_uuid
diff --git a/openstack_dashboard/dashboards/project/access_and_security/urls.py b/openstack_dashboard/dashboards/project/access_and_security/urls.py
deleted file mode 100644
index 9da63fb3..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/urls.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import include
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.access_and_security.\
- api_access import urls as api_access_urls
-from openstack_dashboard.dashboards.project.access_and_security.\
- floating_ips import urls as fip_urls
-from openstack_dashboard.dashboards.project.access_and_security.\
- keypairs import urls as keypair_urls
-from openstack_dashboard.dashboards.project.access_and_security.\
- security_groups import urls as sec_group_urls
-from openstack_dashboard.dashboards.project.access_and_security.views \
- import IndexView
-
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'api_access/', include(api_access_urls, namespace='api_access')),
- url(r'keypairs/', include(keypair_urls, namespace='keypairs')),
- url(r'floating_ips/', include(fip_urls, namespace='floating_ips')),
- url(r'security_groups/',
- include(sec_group_urls, namespace='security_groups')),
-)
diff --git a/openstack_dashboard/dashboards/project/access_and_security/views.py b/openstack_dashboard/dashboards/project/access_and_security/views.py
deleted file mode 100644
index ed4974d4..00000000
--- a/openstack_dashboard/dashboards/project/access_and_security/views.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-# Copyright 2012 OpenStack LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for Instances and Volumes.
-"""
-
-from horizon import tabs
-
-from openstack_dashboard.dashboards.project.access_and_security.tabs \
- import AccessAndSecurityTabs
-
-
-class IndexView(tabs.TabbedTableView):
- tab_group_class = AccessAndSecurityTabs
- template_name = 'project/access_and_security/index.html'
diff --git a/openstack_dashboard/dashboards/project/containers/__init__.py b/openstack_dashboard/dashboards/project/containers/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/containers/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/containers/browsers.py b/openstack_dashboard/dashboards/project/containers/browsers.py
deleted file mode 100644
index 8a5174c5..00000000
--- a/openstack_dashboard/dashboards/project/containers/browsers.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import browsers
-
-from openstack_dashboard.dashboards.project.containers.tables import \
- ContainersTable
-from openstack_dashboard.dashboards.project.containers.tables import \
- ObjectsTable
-
-
-class ContainerBrowser(browsers.ResourceBrowser):
- name = "swift"
- verbose_name = _("Swift")
- navigation_table_class = ContainersTable
- content_table_class = ObjectsTable
- navigable_item_name = _("Container")
- navigation_kwarg_name = "container_name"
- content_kwarg_name = "subfolder_path"
- has_breadcrumb = True
- breadcrumb_url = "horizon:project:containers:index"
diff --git a/openstack_dashboard/dashboards/project/containers/forms.py b/openstack_dashboard/dashboards/project/containers/forms.py
deleted file mode 100644
index ba5d2c87..00000000
--- a/openstack_dashboard/dashboards/project/containers/forms.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.core import validators
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.containers.tables import \
- wrap_delimiter
-
-
-LOG = logging.getLogger(__name__)
-
-
-no_slash_validator = validators.RegexValidator(r'^(?u)[^/]+$',
- _("Slash is not an allowed "
- "character."),
- code="noslash")
-
-
-class CreateContainer(forms.SelfHandlingForm):
- parent = forms.CharField(max_length=255,
- required=False,
- widget=forms.HiddenInput)
- name = forms.CharField(max_length=255,
- label=_("Container Name"),
- validators=[no_slash_validator])
-
- def handle(self, request, data):
- try:
- if not data['parent']:
- # Create a container
- api.swift.swift_create_container(request, data["name"])
- messages.success(request, _("Container created successfully."))
- else:
- # Create a pseudo-folder
- container, slash, remainder = data['parent'].partition("/")
- remainder = remainder.rstrip("/")
- subfolder_name = "/".join([bit for bit
- in (remainder, data['name'])
- if bit])
- api.swift.swift_create_subfolder(request,
- container,
- subfolder_name)
- messages.success(request, _("Folder created successfully."))
- return True
- except:
- exceptions.handle(request, _('Unable to create container.'))
-
-
-class UploadObject(forms.SelfHandlingForm):
- path = forms.CharField(max_length=255,
- required=False,
- widget=forms.HiddenInput)
- name = forms.CharField(max_length=255,
- label=_("Object Name"),
- help_text=_("Slashes are allowed, and are treated "
- "as pseudo-folders by the Object "
- "Store."))
- object_file = forms.FileField(label=_("File"), allow_empty_file=True)
- container_name = forms.CharField(widget=forms.HiddenInput())
-
- def handle(self, request, data):
- object_file = self.files['object_file']
- if data['path']:
- object_path = "/".join([data['path'].rstrip("/"), data['name']])
- else:
- object_path = data['name']
- try:
- obj = api.swift.swift_upload_object(request,
- data['container_name'],
- object_path,
- object_file)
- messages.success(request, _("Object was successfully uploaded."))
- return obj
- except:
- exceptions.handle(request, _("Unable to upload object."))
-
-
-class CopyObject(forms.SelfHandlingForm):
- new_container_name = forms.ChoiceField(label=_("Destination container"),
- validators=[no_slash_validator])
- path = forms.CharField(max_length=255, required=False)
- new_object_name = forms.CharField(max_length=255,
- label=_("Destination object name"),
- validators=[no_slash_validator])
- orig_container_name = forms.CharField(widget=forms.HiddenInput())
- orig_object_name = forms.CharField(widget=forms.HiddenInput())
-
- def __init__(self, *args, **kwargs):
- containers = kwargs.pop('containers')
- super(CopyObject, self).__init__(*args, **kwargs)
- self.fields['new_container_name'].choices = containers
-
- def handle(self, request, data):
- index = "horizon:project:containers:index"
- orig_container = data['orig_container_name']
- orig_object = data['orig_object_name']
- new_container = data['new_container_name']
- new_object = data['new_object_name']
- path = data['path']
- if path and not path.endswith("/"):
- path = path + "/"
- new_path = "%s%s" % (path, new_object)
-
- # Now copy the object itself.
- try:
- api.swift.swift_copy_object(request,
- orig_container,
- orig_object,
- new_container,
- new_path)
- dest = "%s/%s" % (new_container, path)
- vals = {"dest": dest.rstrip("/"),
- "orig": orig_object.split("/")[-1],
- "new": new_object}
- messages.success(request,
- _('Copied "%(orig)s" to "%(dest)s" as "%(new)s".')
- % vals)
- return True
- except exceptions.HorizonException as exc:
- messages.error(request, exc)
- raise exceptions.Http302(reverse(index,
- args=[wrap_delimiter(orig_container)]))
- except:
- redirect = reverse(index, args=[wrap_delimiter(orig_container)])
- exceptions.handle(request,
- _("Unable to copy object."),
- redirect=redirect)
diff --git a/openstack_dashboard/dashboards/project/containers/panel.py b/openstack_dashboard/dashboards/project/containers/panel.py
deleted file mode 100644
index 1f726d49..00000000
--- a/openstack_dashboard/dashboards/project/containers/panel.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.project import dashboard
-
-
-class Containers(horizon.Panel):
- name = _("Containers")
- slug = 'containers'
- permissions = ('openstack.services.object-store',)
-
-dashboard.Project.register(Containers)
diff --git a/openstack_dashboard/dashboards/project/containers/tables.py b/openstack_dashboard/dashboards/project/containers/tables.py
deleted file mode 100644
index ccb9d1bf..00000000
--- a/openstack_dashboard/dashboards/project/containers/tables.py
+++ /dev/null
@@ -1,241 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.template.defaultfilters import filesizeformat
-from django.utils import http
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-from openstack_dashboard import api
-from openstack_dashboard.api.swift import FOLDER_DELIMITER
-
-
-LOG = logging.getLogger(__name__)
-
-
-def wrap_delimiter(name):
- if name and not name.endswith(FOLDER_DELIMITER):
- return name + FOLDER_DELIMITER
- return name
-
-
-class DeleteContainer(tables.DeleteAction):
- data_type_singular = _("Container")
- data_type_plural = _("Containers")
- success_url = "horizon:project:containers:index"
-
- def delete(self, request, obj_id):
- api.swift.swift_delete_container(request, obj_id)
-
- def get_success_url(self, request=None):
- """
- Returns the URL to redirect to after a successful action.
- """
- current_container = self.table.kwargs.get("container_name", None)
-
- # If the current_container is deleted, then redirect to the default
- # completion url
- if current_container in self.success_ids:
- return self.success_url
- return request.get_full_path()
-
-
-class CreateContainer(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Container")
- url = "horizon:project:containers:create"
- classes = ("ajax-modal", "btn-create")
-
-
-class ListObjects(tables.LinkAction):
- name = "list_objects"
- verbose_name = _("View Container")
- url = "horizon:project:containers:index"
- classes = ("btn-list",)
-
- def get_link_url(self, datum=None):
- container_name = http.urlquote(datum.name)
- args = (wrap_delimiter(container_name),)
- return reverse(self.url, args=args)
-
-
-class UploadObject(tables.LinkAction):
- name = "upload"
- verbose_name = _("Upload Object")
- url = "horizon:project:containers:object_upload"
- classes = ("ajax-modal", "btn-upload")
-
- def get_link_url(self, datum=None):
- # Usable for both the container and object tables
- if getattr(datum, 'container', datum):
- # This is a container
- container_name = http.urlquote(datum.name)
- else:
- # This is a table action, and we already have the container name
- container_name = self.table.kwargs['container_name']
- subfolders = self.table.kwargs.get('subfolder_path', '')
- args = (http.urlquote(bit) for bit in
- (container_name, subfolders) if bit)
- return reverse(self.url, args=args)
-
- def allowed(self, request, datum=None):
- if self.table.kwargs.get('container_name', None):
- return True
- return False
-
- def update(self, request, obj):
- # This will only be called for the row, so we can remove the button
- # styles meant for the table action version.
- self.attrs = {'class': 'ajax-modal'}
-
-
-def get_size_used(container):
- return filesizeformat(container.bytes)
-
-
-def get_container_link(container):
- return reverse("horizon:project:containers:index",
- args=(http.urlquote(wrap_delimiter(container.name)),))
-
-
-class ContainersTable(tables.DataTable):
- name = tables.Column("name",
- link=get_container_link,
- verbose_name=_("Container Name"))
-
- def get_object_id(self, container):
- return container.name
-
- class Meta:
- name = "containers"
- verbose_name = _("Containers")
- table_actions = (CreateContainer,)
- row_actions = (DeleteContainer,)
- browser_table = "navigation"
- footer = False
-
-
-class DeleteObject(tables.DeleteAction):
- name = "delete_object"
- data_type_singular = _("Object")
- data_type_plural = _("Objects")
- allowed_data_types = ("objects",)
-
- def delete(self, request, obj_id):
- obj = self.table.get_object_by_id(obj_id)
- container_name = obj.container_name
- api.swift.swift_delete_object(request, container_name, obj_id)
-
-
-class DeleteMultipleObjects(DeleteObject):
- name = "delete_multiple_objects"
- data_type_singular = _("Object")
- data_type_plural = _("Objects")
- allowed_data_types = ("objects",)
-
-
-class CopyObject(tables.LinkAction):
- name = "copy"
- verbose_name = _("Copy")
- url = "horizon:project:containers:object_copy"
- classes = ("ajax-modal", "btn-copy")
- allowed_data_types = ("objects",)
-
- def get_link_url(self, obj):
- container_name = self.table.kwargs['container_name']
- return reverse(self.url, args=(http.urlquote(container_name),
- http.urlquote(obj.name)))
-
-
-class DownloadObject(tables.LinkAction):
- name = "download"
- verbose_name = _("Download")
- url = "horizon:project:containers:object_download"
- classes = ("btn-download",)
- allowed_data_types = ("objects",)
-
- def get_link_url(self, obj):
- container_name = self.table.kwargs['container_name']
- return reverse(self.url, args=(http.urlquote(container_name),
- http.urlquote(obj.name)))
-
-
-class ObjectFilterAction(tables.FilterAction):
- def _filtered_data(self, table, filter_string):
- request = table.request
- container = self.table.kwargs['container_name']
- subfolder = self.table.kwargs['subfolder_path']
- prefix = wrap_delimiter(subfolder) if subfolder else ''
- self.filtered_data = api.swift.swift_filter_objects(request,
- filter_string,
- container,
- prefix=prefix)
- return self.filtered_data
-
- def filter_subfolders_data(self, table, objects, filter_string):
- data = self._filtered_data(table, filter_string)
- return [datum for datum in data if
- datum.content_type == "application/pseudo-folder"]
-
- def filter_objects_data(self, table, objects, filter_string):
- data = self._filtered_data(table, filter_string)
- return [datum for datum in data if
- datum.content_type != "application/pseudo-folder"]
-
- def allowed(self, request, datum=None):
- if self.table.kwargs.get('container_name', None):
- return True
- return False
-
-
-def sanitize_name(name):
- return name.split(FOLDER_DELIMITER)[-1]
-
-
-def get_size(obj):
- if obj.bytes:
- return filesizeformat(obj.bytes)
-
-
-def get_link_subfolder(subfolder):
- container_name = subfolder.container_name
- return reverse("horizon:project:containers:index",
- args=(http.urlquote(wrap_delimiter(container_name)),
- http.urlquote(wrap_delimiter(subfolder.name))))
-
-
-class ObjectsTable(tables.DataTable):
- name = tables.Column("name",
- link=get_link_subfolder,
- allowed_data_types=("subfolders",),
- verbose_name=_("Object Name"),
- filters=(sanitize_name,))
-
- size = tables.Column(get_size, verbose_name=_('Size'))
-
- class Meta:
- name = "objects"
- verbose_name = _("Objects")
- table_actions = (ObjectFilterAction, UploadObject,
- DeleteMultipleObjects)
- row_actions = (DownloadObject, CopyObject, DeleteObject)
- data_types = ("subfolders", "objects")
- browser_table = "content"
- footer = False
diff --git a/openstack_dashboard/dashboards/project/containers/templates/containers/_copy.html b/openstack_dashboard/dashboards/project/containers/templates/containers/_copy.html
deleted file mode 100644
index 8b568ea4..00000000
--- a/openstack_dashboard/dashboards/project/containers/templates/containers/_copy.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}copy_object_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:containers:object_copy' container_name object_name %}{% endblock %}
-
-{% block modal-header %}{% trans "Copy Object" %}: {{ object_name }}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "Make a new copy of an existing object to store in this or another container. You may also specify a path at which the new copy should live inside of the selected container." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Copy Object" %}" />
- <a href="{% url 'horizon:project:containers:index' container_name|add:'/' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/containers/templates/containers/_create.html b/openstack_dashboard/dashboards/project/containers/templates/containers/_create.html
deleted file mode 100644
index 1243f5f5..00000000
--- a/openstack_dashboard/dashboards/project/containers/templates/containers/_create.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_container_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:containers:create' %}{% endblock %}
-
-{% block modal-header %}{% trans "Create Container" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "A container is a storage compartment for your data and provides a way for you to organize your data. You can think of a container as a folder in Windows &reg; or a directory in UNIX &reg;. The primary difference between a container and these other file system concepts is that containers cannot be nested. You can, however, create an unlimited number of containers within your account. Data must be stored in a container so you must have at least one container defined in your account prior to uploading data." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Container" %}" />
- <a href="{% url 'horizon:project:containers:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/containers/templates/containers/_upload.html b/openstack_dashboard/dashboards/project/containers/templates/containers/_upload.html
deleted file mode 100644
index 4d2d7ce2..00000000
--- a/openstack_dashboard/dashboards/project/containers/templates/containers/_upload.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}upload_object_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:containers:object_upload' container_name %}{% endblock %}
-{% block form_attrs %}enctype="multipart/form-data"{% endblock %}
-
-{% block modal-header %}{% trans "Upload Object To Container" %}: {{ container_name }}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p><strong>{% trans "Object" %}</strong>: {% trans "An object is the basic storage entity that represents a file you store in the OpenStack Object Storage system. When you upload data to OpenStack Object Storage, the data is stored as-is (no compression or encryption) and consists of a location (container), the object's name, and any metadata consisting of key/value pairs." %}</p>
- <p><strong>{% trans "Pseudo-folder" %}</strong>: {% trans "Within a container you can group your objects into pseudo-folders, which behave similarly to folders in your desktop operating system, with the exception that they are virtual collections defined by a common prefix on the object's name. A slash (/) character is used as the delimiter for pseudo-folders in the Object Store." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Upload Object" %}" />
- <a href="{% url 'horizon:project:containers:index' container_name|add:'/' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/containers/templates/containers/copy.html b/openstack_dashboard/dashboards/project/containers/templates/containers/copy.html
deleted file mode 100644
index d01cf68b..00000000
--- a/openstack_dashboard/dashboards/project/containers/templates/containers/copy.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Copy Object" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Copy Object") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/containers/_copy.html' %}
-{% endblock %}
-
-
diff --git a/openstack_dashboard/dashboards/project/containers/templates/containers/create.html b/openstack_dashboard/dashboards/project/containers/templates/containers/create.html
deleted file mode 100644
index 804803c1..00000000
--- a/openstack_dashboard/dashboards/project/containers/templates/containers/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Container" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create Container") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "project/containers/_create.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/containers/templates/containers/index.html b/openstack_dashboard/dashboards/project/containers/templates/containers/index.html
deleted file mode 100644
index f59f1c62..00000000
--- a/openstack_dashboard/dashboards/project/containers/templates/containers/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Containers" %}{% endblock %}
-
-{% block page_header %}
- <div class='page-header'>
- <h2>{% trans "Containers" %}</h2>
- </div>
-{% endblock page_header %}
-
-{% block main %}
- {{ swift_browser.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/containers/templates/containers/upload.html b/openstack_dashboard/dashboards/project/containers/templates/containers/upload.html
deleted file mode 100644
index 4f883817..00000000
--- a/openstack_dashboard/dashboards/project/containers/templates/containers/upload.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Upload Object" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Upload Objects") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/containers/_upload.html' %}
-{% endblock %}
-
-
-
-
diff --git a/openstack_dashboard/dashboards/project/containers/tests.py b/openstack_dashboard/dashboards/project/containers/tests.py
deleted file mode 100644
index 193bb0e0..00000000
--- a/openstack_dashboard/dashboards/project/containers/tests.py
+++ /dev/null
@@ -1,239 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import tempfile
-
-from django.core.files.uploadedfile import InMemoryUploadedFile
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.containers import forms
-from openstack_dashboard.dashboards.project.containers.tables import \
- ContainersTable
-from openstack_dashboard.dashboards.project.containers.tables import \
- ObjectsTable
-from openstack_dashboard.dashboards.project.containers.tables import \
- wrap_delimiter
-from openstack_dashboard.test import helpers as test
-
-
-CONTAINER_INDEX_URL = reverse('horizon:project:containers:index')
-
-
-class SwiftTests(test.TestCase):
- @test.create_stubs({api.swift: ('swift_get_containers',)})
- def test_index_no_container_selected(self):
- containers = self.containers.list()
- api.swift.swift_get_containers(IsA(http.HttpRequest), marker=None) \
- .AndReturn((containers, False))
- self.mox.ReplayAll()
-
- res = self.client.get(CONTAINER_INDEX_URL)
-
- self.assertTemplateUsed(res, 'project/containers/index.html')
- self.assertIn('table', res.context)
- resp_containers = res.context['table'].data
- self.assertEqual(len(resp_containers), len(containers))
-
- @test.create_stubs({api.swift: ('swift_delete_container', )})
- def test_delete_container(self):
- container = self.containers.get(name=u"container_two\u6346")
- api.swift.swift_delete_container(IsA(http.HttpRequest), container.name)
- self.mox.ReplayAll()
-
- action_string = u"containers__delete__%s" % container.name
- form_data = {"action": action_string}
- req = self.factory.post(CONTAINER_INDEX_URL, form_data)
- table = ContainersTable(req, self.containers.list())
- handled = table.maybe_handle()
- self.assertEqual(handled['location'], CONTAINER_INDEX_URL)
-
- @test.create_stubs({api.swift: ('swift_get_objects', )})
- def test_delete_container_nonempty(self):
- container = self.containers.first()
- objects = self.objects.list()
- api.swift.swift_get_objects(IsA(http.HttpRequest),
- container.name).AndReturn([objects, False])
- self.mox.ReplayAll()
-
- action_string = u"containers__delete__%s" % container.name
- form_data = {"action": action_string}
- req = self.factory.post(CONTAINER_INDEX_URL, form_data)
- table = ContainersTable(req, self.containers.list())
- handled = table.maybe_handle()
- self.assertEqual(handled['location'], CONTAINER_INDEX_URL)
- self.assertEqual(unicode(list(req._messages)[0].message),
- u"The container cannot be deleted "
- u"since it's not empty.")
-
- def test_create_container_get(self):
- res = self.client.get(reverse('horizon:project:containers:create'))
- self.assertTemplateUsed(res, 'project/containers/create.html')
-
- @test.create_stubs({api.swift: ('swift_create_container',)})
- def test_create_container_post(self):
- api.swift.swift_create_container(IsA(http.HttpRequest),
- self.containers.first().name)
- self.mox.ReplayAll()
-
- formData = {'name': self.containers.first().name,
- 'method': forms.CreateContainer.__name__}
- res = self.client.post(reverse('horizon:project:containers:create'),
- formData)
- url = reverse('horizon:project:containers:index',
- args=[wrap_delimiter(self.containers.first().name)])
- self.assertRedirectsNoFollow(res, url)
-
- @test.create_stubs({api.swift: ('swift_get_containers',
- 'swift_get_objects')})
- def test_index_container_selected(self):
- containers = (self.containers.list(), False)
- ret = (self.objects.list(), False)
- api.swift.swift_get_containers(IsA(http.HttpRequest),
- marker=None).AndReturn(containers)
- api.swift.swift_get_objects(IsA(http.HttpRequest),
- self.containers.first().name,
- marker=None,
- prefix=None).AndReturn(ret)
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:project:containers:index',
- args=[wrap_delimiter(self.containers
- .first()
- .name)]))
- self.assertTemplateUsed(res, 'project/containers/index.html')
- # UTF8 encoding here to ensure there aren't problems with Nose output.
- expected = [obj.name.encode('utf8') for obj in self.objects.list()]
- self.assertQuerysetEqual(res.context['objects_table'].data,
- expected,
- lambda obj: obj.name.encode('utf8'))
-
- @test.create_stubs({api.swift: ('swift_upload_object',)})
- def test_upload(self):
- container = self.containers.first()
- obj = self.objects.first()
- OBJECT_DATA = 'objectData'
-
- temp_file = tempfile.TemporaryFile()
- temp_file.write(OBJECT_DATA)
- temp_file.flush()
- temp_file.seek(0)
-
- api.swift.swift_upload_object(IsA(http.HttpRequest),
- container.name,
- obj.name,
- IsA(InMemoryUploadedFile)).AndReturn(obj)
- self.mox.ReplayAll()
-
- upload_url = reverse('horizon:project:containers:object_upload',
- args=[container.name])
-
- res = self.client.get(upload_url)
- self.assertTemplateUsed(res, 'project/containers/upload.html')
-
- res = self.client.get(upload_url)
- self.assertContains(res, 'enctype="multipart/form-data"')
-
- formData = {'method': forms.UploadObject.__name__,
- 'container_name': container.name,
- 'name': obj.name,
- 'object_file': temp_file}
- res = self.client.post(upload_url, formData)
-
- index_url = reverse('horizon:project:containers:index',
- args=[wrap_delimiter(container.name)])
- self.assertRedirectsNoFollow(res, index_url)
-
- @test.create_stubs({api.swift: ('swift_delete_object',)})
- def test_delete(self):
- container = self.containers.first()
- obj = self.objects.first()
- index_url = reverse('horizon:project:containers:index',
- args=[wrap_delimiter(container.name)])
- api.swift.swift_delete_object(IsA(http.HttpRequest),
- container.name,
- obj.name)
- self.mox.ReplayAll()
-
- action_string = "objects__delete_object__%s" % obj.name
- form_data = {"action": action_string}
- req = self.factory.post(index_url, form_data)
- kwargs = {"container_name": container.name}
- table = ObjectsTable(req, self.objects.list(), **kwargs)
- handled = table.maybe_handle()
- self.assertEqual(handled['location'], index_url)
-
- @test.create_stubs({api.swift: ('swift_get_object',)})
- def test_download(self):
- container = self.containers.first()
- obj = self.objects.first()
-
- api.swift.swift_get_object(IsA(http.HttpRequest),
- container.name,
- obj.name).AndReturn(obj)
- self.mox.ReplayAll()
-
- download_url = reverse('horizon:project:containers:object_download',
- args=[container.name, obj.name])
- res = self.client.get(download_url)
- self.assertEqual(res.content, obj.data)
- self.assertTrue(res.has_header('Content-Disposition'))
-
- @test.create_stubs({api.swift: ('swift_get_containers',)})
- def test_copy_index(self):
- ret = (self.containers.list(), False)
- api.swift.swift_get_containers(IsA(http.HttpRequest)).AndReturn(ret)
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:project:containers:object_copy',
- args=[self.containers.first().name,
- self.objects.first().name]))
- self.assertTemplateUsed(res, 'project/containers/copy.html')
-
- @test.create_stubs({api.swift: ('swift_get_containers',
- 'swift_copy_object')})
- def test_copy(self):
- container_1 = self.containers.get(name=u"container_one\u6346")
- container_2 = self.containers.get(name=u"container_two\u6346")
- obj = self.objects.first()
-
- ret = (self.containers.list(), False)
- api.swift.swift_get_containers(IsA(http.HttpRequest)).AndReturn(ret)
- api.swift.swift_copy_object(IsA(http.HttpRequest),
- container_1.name,
- obj.name,
- container_2.name,
- obj.name)
- self.mox.ReplayAll()
-
- formData = {'method': forms.CopyObject.__name__,
- 'new_container_name': container_2.name,
- 'new_object_name': obj.name,
- 'orig_container_name': container_1.name,
- 'orig_object_name': obj.name}
- copy_url = reverse('horizon:project:containers:object_copy',
- args=[container_1.name, obj.name])
- res = self.client.post(copy_url, formData)
- index_url = reverse('horizon:project:containers:index',
- args=[wrap_delimiter(container_2.name)])
- self.assertRedirectsNoFollow(res, index_url)
diff --git a/openstack_dashboard/dashboards/project/containers/urls.py b/openstack_dashboard/dashboards/project/containers/urls.py
deleted file mode 100644
index 46c71cc7..00000000
--- a/openstack_dashboard/dashboards/project/containers/urls.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.containers.views import \
- ContainerView
-from openstack_dashboard.dashboards.project.containers.views import CopyView
-from openstack_dashboard.dashboards.project.containers.views import CreateView
-from openstack_dashboard.dashboards.project.containers.views import UploadView
-
-
-VIEW_MOD = 'openstack_dashboard.dashboards.project.containers.views'
-
-# Swift containers and objects.
-urlpatterns = patterns(VIEW_MOD,
- url(r'^((?P<container_name>.+?)/)?(?P<subfolder_path>(.+/)+)?$',
- ContainerView.as_view(), name='index'),
-
- url(r'^(?P<container_name>(.+/)+)?create$',
- CreateView.as_view(),
- name='create'),
-
- url(r'^(?P<container_name>.+?)/(?P<subfolder_path>(.+/)+)?upload$',
- UploadView.as_view(),
- name='object_upload'),
-
- url(r'^(?P<container_name>[^/]+)/'
- r'(?P<subfolder_path>(.+/)+)?'
- r'(?P<object_name>.+)/copy$',
- CopyView.as_view(),
- name='object_copy'),
-
- url(r'^(?P<container_name>[^/]+)/(?P<object_path>.+)/download$',
- 'object_download',
- name='object_download')
-)
diff --git a/openstack_dashboard/dashboards/project/containers/views.py b/openstack_dashboard/dashboards/project/containers/views.py
deleted file mode 100644
index 28777468..00000000
--- a/openstack_dashboard/dashboards/project/containers/views.py
+++ /dev/null
@@ -1,228 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing Swift containers.
-"""
-
-from django.core.urlresolvers import reverse
-from django import http
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import browsers
-from horizon import exceptions
-from horizon import forms
-
-from openstack_dashboard import api
-from openstack_dashboard.api.swift import FOLDER_DELIMITER
-from openstack_dashboard.dashboards.project.containers.browsers \
- import ContainerBrowser
-from openstack_dashboard.dashboards.project.containers.forms import CopyObject
-from openstack_dashboard.dashboards.project.containers.forms \
- import CreateContainer
-from openstack_dashboard.dashboards.project.containers.forms \
- import UploadObject
-from openstack_dashboard.dashboards.project.containers.tables \
- import wrap_delimiter
-
-import os
-
-
-class ContainerView(browsers.ResourceBrowserView):
- browser_class = ContainerBrowser
- template_name = "project/containers/index.html"
-
- def get_containers_data(self):
- containers = []
- self._more = None
- marker = self.request.GET.get('marker', None)
- try:
- containers, self._more = api.swift.swift_get_containers(
- self.request, marker=marker)
- except:
- msg = _('Unable to retrieve container list.')
- exceptions.handle(self.request, msg)
- return containers
-
- @property
- def objects(self):
- """ Returns a list of objects given the subfolder's path.
-
- The path is from the kwargs of the request.
- """
- if not hasattr(self, "_objects"):
- objects = []
- self._more = None
- marker = self.request.GET.get('marker', None)
- container_name = self.kwargs['container_name']
- subfolder = self.kwargs['subfolder_path']
- prefix = None
- if container_name:
- self.navigation_selection = True
- if subfolder:
- prefix = subfolder
- try:
- objects, self._more = api.swift.swift_get_objects(
- self.request,
- container_name,
- marker=marker,
- prefix=prefix)
- except:
- self._more = None
- objects = []
- msg = _('Unable to retrieve object list.')
- exceptions.handle(self.request, msg)
- self._objects = objects
- return self._objects
-
- def is_subdir(self, item):
- content_type = "application/pseudo-folder"
- return getattr(item, "content_type", None) == content_type
-
- def get_objects_data(self):
- """ Returns a list of objects within the current folder. """
- filtered_objects = [item for item in self.objects
- if not self.is_subdir(item)]
- return filtered_objects
-
- def get_subfolders_data(self):
- """ Returns a list of subfolders within the current folder. """
- filtered_objects = [item for item in self.objects
- if self.is_subdir(item)]
- return filtered_objects
-
- def get_context_data(self, **kwargs):
- context = super(ContainerView, self).get_context_data(**kwargs)
- context['container_name'] = self.kwargs["container_name"]
- context['subfolders'] = []
- if self.kwargs["subfolder_path"]:
- (parent, slash, folder) = self.kwargs["subfolder_path"] \
- .strip('/').rpartition('/')
- while folder:
- path = "%s%s%s/" % (parent, slash, folder)
- context['subfolders'].insert(0, (folder, path))
- (parent, slash, folder) = parent.rpartition('/')
- return context
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateContainer
- template_name = 'project/containers/create.html'
- success_url = "horizon:project:containers:index"
-
- def get_success_url(self):
- parent = self.request.POST.get('parent', None)
- if parent:
- container, slash, remainder = parent.partition(FOLDER_DELIMITER)
- container += FOLDER_DELIMITER
- if remainder and not remainder.endswith(FOLDER_DELIMITER):
- remainder = "".join([remainder, FOLDER_DELIMITER])
- return reverse(self.success_url, args=(container, remainder))
- else:
- return reverse(self.success_url, args=[self.request.POST['name'] +
- FOLDER_DELIMITER])
-
- def get_initial(self):
- initial = super(CreateView, self).get_initial()
- initial['parent'] = self.kwargs['container_name']
- return initial
-
-
-class UploadView(forms.ModalFormView):
- form_class = UploadObject
- template_name = 'project/containers/upload.html'
- success_url = "horizon:project:containers:index"
-
- def get_success_url(self):
- container_name = self.request.POST['container_name']
- return reverse(self.success_url,
- args=(wrap_delimiter(container_name),
- self.request.POST.get('path', '')))
-
- def get_initial(self):
- return {"container_name": self.kwargs["container_name"],
- "path": self.kwargs['subfolder_path']}
-
- def get_context_data(self, **kwargs):
- context = super(UploadView, self).get_context_data(**kwargs)
- context['container_name'] = self.kwargs["container_name"]
- return context
-
-
-def object_download(request, container_name, object_path):
- try:
- obj = api.swift.swift_get_object(request, container_name, object_path)
- except:
- redirect = reverse("horizon:project:containers:index")
- exceptions.handle(request,
- _("Unable to retrieve object."),
- redirect=redirect)
- # Add the original file extension back on if it wasn't preserved in the
- # name given to the object.
- filename = object_path.rsplit(FOLDER_DELIMITER)[-1]
- if not os.path.splitext(obj.name)[1] and obj.orig_name:
- name, ext = os.path.splitext(obj.orig_name)
- filename = "%s%s" % (filename, ext)
- response = http.HttpResponse()
- safe_name = filename.replace(",", "").encode('utf-8')
- response['Content-Disposition'] = 'attachment; filename=%s' % safe_name
- response['Content-Type'] = 'application/octet-stream'
- response.write(obj.data)
- return response
-
-
-class CopyView(forms.ModalFormView):
- form_class = CopyObject
- template_name = 'project/containers/copy.html'
- success_url = "horizon:project:containers:index"
-
- def get_success_url(self):
- new_container_name = self.request.POST['new_container_name']
- return reverse(self.success_url,
- args=(wrap_delimiter(new_container_name),
- wrap_delimiter(self.request.POST.get('path',
- ''))))
-
- def get_form_kwargs(self):
- kwargs = super(CopyView, self).get_form_kwargs()
- try:
- containers = api.swift.swift_get_containers(self.request)
- except:
- redirect = reverse("horizon:project:containers:index")
- exceptions.handle(self.request,
- _('Unable to list containers.'),
- redirect=redirect)
- kwargs['containers'] = [(c.name, c.name) for c in containers[0]]
- return kwargs
-
- def get_initial(self):
- path = self.kwargs["subfolder_path"]
- orig = "%s%s" % (path or '', self.kwargs["object_name"])
- return {"new_container_name": self.kwargs["container_name"],
- "orig_container_name": self.kwargs["container_name"],
- "orig_object_name": orig,
- "path": path,
- "new_object_name": "%s copy" % self.kwargs["object_name"]}
-
- def get_context_data(self, **kwargs):
- context = super(CopyView, self).get_context_data(**kwargs)
- context['container_name'] = self.kwargs["container_name"]
- context['object_name'] = self.kwargs["object_name"]
- return context
diff --git a/openstack_dashboard/dashboards/project/dashboard.py b/openstack_dashboard/dashboards/project/dashboard.py
deleted file mode 100644
index 673acdd3..00000000
--- a/openstack_dashboard/dashboards/project/dashboard.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-
-class BasePanels(horizon.PanelGroup):
- slug = "compute"
- name = _("Manage Compute")
- panels = ('overview',
- 'instances',
- 'volumes',
- 'images_and_snapshots',
- 'access_and_security',)
-
-
-class NetworkPanels(horizon.PanelGroup):
- slug = "network"
- name = _("Manage Network")
- panels = ('networks',
- 'routers',
- 'loadbalancers',
- 'network_topology',)
-
-
-class ObjectStorePanels(horizon.PanelGroup):
- slug = "object_store"
- name = _("Object Store")
- panels = ('containers',)
-
-
-class OrchestrationPanels(horizon.PanelGroup):
- name = _("Orchestration")
- slug = "orchestration"
- panels = ('stacks',)
-
-
-class Project(horizon.Dashboard):
- name = _("Project")
- slug = "project"
- panels = (
- BasePanels, NetworkPanels, ObjectStorePanels, OrchestrationPanels)
- default_panel = 'overview'
- supports_tenants = True
-
-
-horizon.register(Project)
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/__init__.py b/openstack_dashboard/dashboards/project/images_and_snapshots/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/images/__init__.py b/openstack_dashboard/dashboards/project/images_and_snapshots/images/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/images/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/images/forms.py b/openstack_dashboard/dashboards/project/images_and_snapshots/images/forms.py
deleted file mode 100644
index c8876374..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/images/forms.py
+++ /dev/null
@@ -1,223 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing images.
-"""
-
-import logging
-
-from django.conf import settings
-from django.forms import ValidationError
-from django.forms.widgets import HiddenInput
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateImageForm(forms.SelfHandlingForm):
- name = forms.CharField(max_length="255", label=_("Name"), required=True)
- description = forms.CharField(widget=forms.widgets.Textarea(),
- label=_("Description"),
- required=False)
-
- source_type = forms.ChoiceField(
- label=_('Image Source'),
- choices=[('url', _('Image Location')),
- ('file', _('Image File'))],
- widget=forms.Select(attrs={
- 'class': 'switchable',
- 'data-slug': 'source'}))
-
- copy_from = forms.CharField(max_length="255",
- label=_("Image Location"),
- help_text=_("An external (HTTP) URL to load "
- "the image from."),
- widget=forms.TextInput(attrs={
- 'class': 'switched',
- 'data-switch-on': 'source',
- 'data-source-url': _('Image Location')}),
- required=False)
- image_file = forms.FileField(label=_("Image File"),
- help_text=("A local image to upload."),
- widget=forms.FileInput(attrs={
- 'class': 'switched',
- 'data-switch-on': 'source',
- 'data-source-file': _('Image File')}),
- required=False)
- disk_format = forms.ChoiceField(label=_('Format'),
- required=True,
- choices=[('', ''),
- ('aki',
- _('AKI - Amazon Kernel '
- 'Image')),
- ('ami',
- _('AMI - Amazon Machine '
- 'Image')),
- ('ari',
- _('ARI - Amazon Ramdisk '
- 'Image')),
- ('iso',
- _('ISO - Optical Disk Image')),
- ('qcow2',
- _('QCOW2 - QEMU Emulator')),
- ('raw', 'Raw'),
- ('vdi', 'VDI'),
- ('vhd', 'VHD'),
- ('vmdk', 'VMDK')],
- widget=forms.Select(attrs={'class':
- 'switchable'}))
- minimum_disk = forms.IntegerField(label=_("Minimum Disk (GB)"),
- help_text=_('The minimum disk size'
- ' required to boot the'
- ' image. If unspecified, this'
- ' value defaults to 0'
- ' (no minimum).'),
- required=False)
- minimum_ram = forms.IntegerField(label=_("Minimum Ram (MB)"),
- help_text=_('The minimum disk size'
- ' required to boot the'
- ' image. If unspecified, this'
- ' value defaults to 0 (no'
- ' minimum).'),
- required=False)
- is_public = forms.BooleanField(label=_("Public"), required=False)
- protected = forms.BooleanField(label=_("Protected"), required=False)
-
- def __init__(self, *args, **kwargs):
- super(CreateImageForm, self).__init__(*args, **kwargs)
- if not settings.HORIZON_IMAGES_ALLOW_UPLOAD:
- self.fields['image_file'].widget = HiddenInput()
-
- def clean(self):
- data = super(CreateImageForm, self).clean()
- if not data['copy_from'] and not data['image_file']:
- raise ValidationError(
- _("A image or external image location must be specified."))
- elif data['copy_from'] and data['image_file']:
- raise ValidationError(
- _("Can not specify both image and external image location."))
- else:
- return data
-
- def handle(self, request, data):
- # Glance does not really do anything with container_format at the
- # moment. It requires it is set to the same disk_format for the three
- # Amazon image types, otherwise it just treats them as 'bare.' As such
- # we will just set that to be that here instead of bothering the user
- # with asking them for information we can already determine.
- if data['disk_format'] in ('ami', 'aki', 'ari',):
- container_format = data['disk_format']
- else:
- container_format = 'bare'
-
- meta = {'is_public': data['is_public'],
- 'protected': data['protected'],
- 'disk_format': data['disk_format'],
- 'container_format': container_format,
- 'min_disk': (data['minimum_disk'] or 0),
- 'min_ram': (data['minimum_ram'] or 0),
- 'name': data['name'],
- 'properties': {}}
-
- if data['description']:
- meta['properties']['description'] = data['description']
- if settings.HORIZON_IMAGES_ALLOW_UPLOAD and data['image_file']:
- meta['data'] = self.files['image_file']
- else:
- meta['copy_from'] = data['copy_from']
-
- try:
- image = api.glance.image_create(request, **meta)
- messages.success(request,
- _('Your image %s has been queued for creation.' %
- data['name']))
- return image
- except:
- exceptions.handle(request, _('Unable to create new image.'))
-
-
-class UpdateImageForm(forms.SelfHandlingForm):
- image_id = forms.CharField(widget=forms.HiddenInput())
- name = forms.CharField(max_length="255", label=_("Name"))
- description = forms.CharField(widget=forms.widgets.Textarea(),
- label=_("Description"),
- required=False)
- kernel = forms.CharField(max_length="36", label=_("Kernel ID"),
- required=False,
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}
- ))
- ramdisk = forms.CharField(max_length="36", label=_("Ramdisk ID"),
- required=False,
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}
- ))
- architecture = forms.CharField(label=_("Architecture"), required=False,
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}
- ))
- disk_format = forms.CharField(label=_("Format"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}
- ))
- public = forms.BooleanField(label=_("Public"), required=False)
- protected = forms.BooleanField(label=_("Protected"), required=False)
-
- def handle(self, request, data):
- image_id = data['image_id']
- error_updating = _('Unable to update image "%s".')
-
- if data['disk_format'] in ['aki', 'ari', 'ami']:
- container_format = data['disk_format']
- else:
- container_format = 'bare'
-
- meta = {'is_public': data['public'],
- 'protected': data['protected'],
- 'disk_format': data['disk_format'],
- 'container_format': container_format,
- 'name': data['name'],
- 'properties': {}}
- if data['description']:
- meta['properties']['description'] = data['description']
- if data['kernel']:
- meta['properties']['kernel_id'] = data['kernel']
- if data['ramdisk']:
- meta['properties']['ramdisk_id'] = data['ramdisk']
- if data['architecture']:
- meta['properties']['architecture'] = data['architecture']
- # Ensure we do not delete properties that have already been
- # set on an image.
- meta['purge_props'] = False
-
- try:
- image = api.glance.image_update(request, image_id, **meta)
- messages.success(request, _('Image was successfully updated.'))
- return image
- except:
- exceptions.handle(request, error_updating % image_id)
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/images/tables.py b/openstack_dashboard/dashboards/project/images_and_snapshots/images/tables.py
deleted file mode 100644
index d2871f56..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/images/tables.py
+++ /dev/null
@@ -1,229 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from collections import defaultdict
-import logging
-
-from django.conf import settings
-from django.core.urlresolvers import reverse
-from django.template import defaultfilters as filters
-from django.utils.http import urlencode
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-from horizon.utils.memoized import memoized
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class LaunchImage(tables.LinkAction):
- name = "launch_image"
- verbose_name = _("Launch")
- url = "horizon:project:instances:launch"
- classes = ("btn-launch", "ajax-modal")
-
- def get_link_url(self, datum):
- base_url = reverse(self.url)
-
- if get_image_type(datum) == "image":
- source_type = "image_id"
- else:
- source_type = "instance_snapshot_id"
-
- params = urlencode({"source_type": source_type,
- "source_id": self.table.get_object_id(datum)})
- return "?".join([base_url, params])
-
- def allowed(self, request, image=None):
- if image:
- return image.status in ("active",)
- return False
-
-
-class DeleteImage(tables.DeleteAction):
- data_type_singular = _("Image")
- data_type_plural = _("Images")
-
- def allowed(self, request, image=None):
- # Protected images can not be deleted.
- if image and image.protected:
- return False
- if image:
- return image.owner == request.user.tenant_id
- # Return True to allow table-level bulk delete action to appear.
- return True
-
- def delete(self, request, obj_id):
- api.glance.image_delete(request, obj_id)
-
-
-class CreateImage(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Image")
- url = "horizon:project:images_and_snapshots:images:create"
- classes = ("ajax-modal", "btn-create")
-
-
-class EditImage(tables.LinkAction):
- name = "edit"
- verbose_name = _("Edit")
- url = "horizon:project:images_and_snapshots:images:update"
- classes = ("ajax-modal", "btn-edit")
-
- def allowed(self, request, image=None):
- if image:
- return image.status in ("active",) and \
- image.owner == request.user.tenant_id
- # We don't have bulk editing, so if there isn't an image that's
- # authorized, don't allow the action.
- return False
-
-
-class CreateVolumeFromImage(tables.LinkAction):
- name = "create_volume_from_image"
- verbose_name = _("Create Volume")
- url = "horizon:project:volumes:create"
- classes = ("ajax-modal", "btn-camera")
-
- def get_link_url(self, datum):
- base_url = reverse(self.url)
- params = urlencode({"image_id": self.table.get_object_id(datum)})
- return "?".join([base_url, params])
-
- def allowed(self, request, image=None):
- if image:
- return image.status == "active"
- return False
-
-
-def filter_tenants():
- return getattr(settings, 'IMAGES_LIST_FILTER_TENANTS', [])
-
-
-@memoized
-def filter_tenant_ids():
- return map(lambda ft: ft['tenant'], filter_tenants())
-
-
-class OwnerFilter(tables.FixedFilterAction):
- def get_fixed_buttons(self):
- def make_dict(text, tenant, icon):
- return dict(text=text, value=tenant, icon=icon)
-
- buttons = [make_dict(_('Project'), 'project', 'icon-home')]
- for button_dict in filter_tenants():
- new_dict = button_dict.copy()
- new_dict['value'] = new_dict['tenant']
- buttons.append(new_dict)
- buttons.append(make_dict(_('Shared with Me'), 'shared', 'icon-share'))
- buttons.append(make_dict(_('Public'), 'public', 'icon-fire'))
- return buttons
-
- def categorize(self, table, images):
- user_tenant_id = table.request.user.tenant_id
- tenants = defaultdict(list)
- for im in images:
- categories = get_image_categories(im, user_tenant_id)
- for category in categories:
- tenants[category].append(im)
- return tenants
-
-
-def get_image_categories(im, user_tenant_id):
- categories = []
- if im.is_public:
- categories.append('public')
- if im.owner == user_tenant_id:
- categories.append('project')
- elif im.owner in filter_tenant_ids():
- categories.append(im.owner)
- elif not im.is_public:
- categories.append('shared')
- return categories
-
-
-def get_image_type(image):
- return getattr(image, "properties", {}).get("image_type", "image")
-
-
-def get_format(image):
- format = getattr(image, "disk_format", "")
- # The "container_format" attribute can actually be set to None,
- # which will raise an error if you call upper() on it.
- if format is not None:
- return format.upper()
-
-
-class UpdateRow(tables.Row):
- ajax = True
-
- def get_data(self, request, image_id):
- image = api.glance.image_get(request, image_id)
- return image
-
- def load_cells(self, image=None):
- super(UpdateRow, self).load_cells(image)
- # Tag the row with the image category for client-side filtering.
- image = self.datum
- my_tenant_id = self.table.request.user.tenant_id
- image_categories = get_image_categories(image, my_tenant_id)
- for category in image_categories:
- self.classes.append('category-' + category)
-
-
-class ImagesTable(tables.DataTable):
- STATUS_CHOICES = (
- ("active", True),
- ("saving", None),
- ("queued", None),
- ("pending_delete", None),
- ("killed", False),
- ("deleted", False),
- )
- name = tables.Column("name",
- link=("horizon:project:images_and_snapshots:"
- "images:detail"),
- verbose_name=_("Image Name"))
- image_type = tables.Column(get_image_type,
- verbose_name=_("Type"),
- filters=(filters.title,))
- status = tables.Column("status",
- filters=(filters.title,),
- verbose_name=_("Status"),
- status=True,
- status_choices=STATUS_CHOICES)
- public = tables.Column("is_public",
- verbose_name=_("Public"),
- empty_value=False,
- filters=(filters.yesno, filters.capfirst))
- protected = tables.Column("protected",
- verbose_name=_("Protected"),
- empty_value=False,
- filters=(filters.yesno, filters.capfirst))
- disk_format = tables.Column(get_format, verbose_name=_("Format"))
-
- class Meta:
- name = "images"
- row_class = UpdateRow
- status_columns = ["status"]
- verbose_name = _("Images")
- table_actions = (OwnerFilter, CreateImage, DeleteImage,)
- row_actions = (LaunchImage, CreateVolumeFromImage,
- EditImage, DeleteImage,)
- pagination_param = "image_marker"
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/images/tabs.py b/openstack_dashboard/dashboards/project/images_and_snapshots/images/tabs.py
deleted file mode 100644
index fefc6816..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/images/tabs.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-
-from openstack_dashboard import api
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "overview"
- template_name = "project/images_and_snapshots/images/_detail_overview.html"
-
- def get_context_data(self, request):
- image_id = self.tab_group.kwargs['image_id']
- try:
- image = api.glance.image_get(self.request, image_id)
- except:
- redirect = reverse('horizon:project:images_and_snapshots:index')
- exceptions.handle(request,
- _('Unable to retrieve image details.'),
- redirect=redirect)
- return {'image': image}
-
-
-class ImageDetailTabs(tabs.TabGroup):
- slug = "image_details"
- tabs = (OverviewTab,)
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/images/tests.py b/openstack_dashboard/dashboards/project/images_and_snapshots/images/tests.py
deleted file mode 100644
index 585804cb..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/images/tests.py
+++ /dev/null
@@ -1,264 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import tempfile
-
-from django.conf import settings
-from django.core.files.uploadedfile import InMemoryUploadedFile
-from django.core.urlresolvers import reverse
-from django.forms.widgets import HiddenInput
-from django import http
-from django.test.utils import override_settings
-
-from mox import IsA
-
-from horizon import tables as horizon_tables
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-from openstack_dashboard.dashboards.project.images_and_snapshots.images.forms \
- import CreateImageForm
-from openstack_dashboard.dashboards.project.images_and_snapshots.images \
- import tables
-
-
-IMAGES_INDEX_URL = reverse('horizon:project:images_and_snapshots:index')
-
-
-class CreateImageFormTests(test.TestCase):
- def test_no_location_or_file(self):
- """
- The form will not be valid if both copy_from and image_file are not
- provided.
- """
- post = {
- 'name': u'Ubuntu 11.10',
- 'source_type': u'file',
- 'description': u'Login with admin/admin',
- 'disk_format': u'qcow2',
- 'minimum_disk': 15,
- 'minimum_ram': 512,
- 'is_public': 1}
- files = {}
- form = CreateImageForm(post, files)
- self.assertEqual(form.is_valid(), False)
-
- @override_settings(HORIZON_IMAGES_ALLOW_UPLOAD=False)
- def test_image_upload_disabled(self):
- """
- If HORIZON_IMAGES_ALLOW_UPLOAD is false, the image_file field widget
- will be a HiddenInput widget instead of a FileInput widget.
- """
- form = CreateImageForm({})
- self.assertEqual(
- isinstance(form.fields['image_file'].widget, HiddenInput), True)
-
-
-class ImageViewTests(test.TestCase):
- def test_image_create_get(self):
- url = reverse('horizon:project:images_and_snapshots:images:create')
- res = self.client.get(url)
- self.assertTemplateUsed(res,
- 'project/images_and_snapshots/images/create.html')
-
- @test.create_stubs({api.glance: ('image_create',)})
- def test_image_create_post_copy_from(self):
- data = {
- 'name': u'Ubuntu 11.10',
- 'description': u'Login with admin/admin',
- 'source_type': u'url',
- 'copy_from': u'http://cloud-images.ubuntu.com/releases/'
- u'oneiric/release/ubuntu-11.10-server-cloudimg'
- u'-amd64-disk1.img',
- 'disk_format': u'qcow2',
- 'minimum_disk': 15,
- 'minimum_ram': 512,
- 'is_public': True,
- 'protected': False,
- 'method': 'CreateImageForm'}
-
- api.glance.image_create(IsA(http.HttpRequest),
- container_format="bare",
- copy_from=data['copy_from'],
- disk_format=data['disk_format'],
- is_public=True,
- protected=False,
- min_disk=data['minimum_disk'],
- min_ram=data['minimum_ram'],
- properties={
- 'description': data['description']},
- name=data['name']). \
- AndReturn(self.images.first())
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:images_and_snapshots:images:create')
- res = self.client.post(url, data)
-
- self.assertNoFormErrors(res)
- self.assertEqual(res.status_code, 302)
-
- @test.create_stubs({api.glance: ('image_create',)})
- def test_image_create_post_upload(self):
- temp_file = tempfile.TemporaryFile()
- temp_file.write('123')
- temp_file.flush()
- temp_file.seek(0)
- data = {
- 'name': u'Test Image',
- 'description': u'Login with admin/admin',
- 'source_type': u'file',
- 'image_file': temp_file,
- 'disk_format': u'qcow2',
- 'minimum_disk': 15,
- 'minimum_ram': 512,
- 'is_public': True,
- 'protected': False,
- 'method': 'CreateImageForm'}
-
- api.glance.image_create(IsA(http.HttpRequest),
- container_format="bare",
- disk_format=data['disk_format'],
- is_public=True,
- protected=False,
- min_disk=data['minimum_disk'],
- min_ram=data['minimum_ram'],
- properties={
- 'description': data['description']},
- name=data['name'],
- data=IsA(InMemoryUploadedFile)). \
- AndReturn(self.images.first())
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:images_and_snapshots:images:create')
- res = self.client.post(url, data)
-
- self.assertNoFormErrors(res)
- self.assertEqual(res.status_code, 302)
-
- @test.create_stubs({api.glance: ('image_get',)})
- def test_image_detail_get(self):
- image = self.images.first()
-
- api.glance.image_get(IsA(http.HttpRequest), str(image.id)) \
- .AndReturn(self.images.first())
- self.mox.ReplayAll()
-
- res = self.client.get(
- reverse('horizon:project:images_and_snapshots:images:detail',
- args=[image.id]))
- self.assertTemplateUsed(res,
- 'project/images_and_snapshots/images/detail.html')
- self.assertEqual(res.context['image'].name, image.name)
- self.assertEqual(res.context['image'].protected, image.protected)
-
- @test.create_stubs({api.glance: ('image_get',)})
- def test_protected_image_detail_get(self):
- image = self.images.list()[2]
-
- api.glance.image_get(IsA(http.HttpRequest), str(image.id)) \
- .AndReturn(image)
- self.mox.ReplayAll()
-
- res = self.client.get(
- reverse('horizon:project:images_and_snapshots:images:detail',
- args=[image.id]))
- self.assertTemplateUsed(res,
- 'project/images_and_snapshots/images/detail.html')
- self.assertEqual(res.context['image'].protected, image.protected)
-
- @test.create_stubs({api.glance: ('image_get',)})
- def test_image_detail_get_with_exception(self):
- image = self.images.first()
-
- api.glance.image_get(IsA(http.HttpRequest), str(image.id)) \
- .AndRaise(self.exceptions.glance)
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:images_and_snapshots:images:detail',
- args=[image.id])
- res = self.client.get(url)
- self.assertRedirectsNoFollow(res, IMAGES_INDEX_URL)
-
- @test.create_stubs({api.glance: ('image_get',)})
- def test_image_update_get(self):
- image = self.images.first()
- image.disk_format = "ami"
- image.is_public = True
- api.glance.image_get(IsA(http.HttpRequest), str(image.id)) \
- .AndReturn(image)
- self.mox.ReplayAll()
-
- res = self.client.get(
- reverse('horizon:project:images_and_snapshots:images:update',
- args=[image.id]))
-
- self.assertTemplateUsed(res,
- 'project/images_and_snapshots/images/_update.html')
- self.assertEqual(res.context['image'].name, image.name)
- # Bug 1076216 - is_public checkbox not being set correctly
- self.assertContains(res, "<input type='checkbox' id='id_public'"
- " name='public' checked='checked'>",
- html=True,
- msg_prefix="The is_public checkbox is not checked")
-
-
-class OwnerFilterTests(test.TestCase):
- def setUp(self):
- super(OwnerFilterTests, self).setUp()
- self.table = self.mox.CreateMock(horizon_tables.DataTable)
- self.table.request = self.request
-
- @override_settings(IMAGES_LIST_FILTER_TENANTS=[{'name': 'Official',
- 'tenant': 'officialtenant',
- 'icon': 'icon-ok'}])
- def test_filter(self):
- self.mox.ReplayAll()
- all_images = self.images.list()
- table = self.table
- self.filter_tenants = settings.IMAGES_LIST_FILTER_TENANTS
-
- filter_ = tables.OwnerFilter()
-
- images = filter_.filter(table, all_images, 'project')
- self.assertEqual(images, self._expected('project'))
-
- images = filter_.filter(table, all_images, 'public')
- self.assertEqual(images, self._expected('public'))
-
- images = filter_.filter(table, all_images, 'shared')
- self.assertEqual(images, self._expected('shared'))
-
- images = filter_.filter(table, all_images, 'officialtenant')
- self.assertEqual(images, self._expected('officialtenant'))
-
- def _expected(self, filter_string):
- my_tenant_id = self.request.user.tenant_id
- images = self.images.list()
- special = map(lambda t: t['tenant'], self.filter_tenants)
-
- if filter_string == 'public':
- return filter(lambda im: im.is_public, images)
- if filter_string == 'shared':
- return filter(lambda im: not im.is_public and
- im.owner != my_tenant_id and
- im.owner not in special, images)
- if filter_string == 'project':
- filter_string = my_tenant_id
- return filter(lambda im: im.owner == filter_string, images)
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/images/urls.py b/openstack_dashboard/dashboards/project/images_and_snapshots/images/urls.py
deleted file mode 100644
index 7ba26d89..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/images/urls.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.images_and_snapshots.images.views \
- import CreateView
-from openstack_dashboard.dashboards.project.images_and_snapshots.images.views \
- import DetailView
-from openstack_dashboard.dashboards.project.images_and_snapshots.images.views \
- import UpdateView
-
-
-VIEWS_MOD = ('openstack_dashboard.dashboards.project'
- '.images_and_snapshots.images.views')
-
-
-urlpatterns = patterns(VIEWS_MOD,
- url(r'^create/$', CreateView.as_view(), name='create'),
- url(r'^(?P<image_id>[^/]+)/update/$', UpdateView.as_view(), name='update'),
- url(r'^(?P<image_id>[^/]+)/$', DetailView.as_view(), name='detail'),
-)
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/images/views.py b/openstack_dashboard/dashboards/project/images_and_snapshots/images/views.py
deleted file mode 100644
index 0ac395a4..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/images/views.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing images.
-"""
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tabs
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.project.images_and_snapshots.images.forms \
- import CreateImageForm
-from openstack_dashboard.dashboards.project.images_and_snapshots.images.forms \
- import UpdateImageForm
-from openstack_dashboard.dashboards.project.images_and_snapshots.images.tabs \
- import ImageDetailTabs
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateImageForm
- template_name = 'project/images_and_snapshots/images/create.html'
- context_object_name = 'image'
- success_url = reverse_lazy("horizon:project:images_and_snapshots:index")
-
-
-class UpdateView(forms.ModalFormView):
- form_class = UpdateImageForm
- template_name = 'project/images_and_snapshots/images/update.html'
- success_url = reverse_lazy("horizon:project:images_and_snapshots:index")
-
- def get_object(self):
- if not hasattr(self, "_object"):
- try:
- self._object = api.glance.image_get(self.request,
- self.kwargs['image_id'])
- except:
- msg = _('Unable to retrieve image.')
- url = reverse('horizon:project:images_and_snapshots:index')
- exceptions.handle(self.request, msg, redirect=url)
- return self._object
-
- def get_context_data(self, **kwargs):
- context = super(UpdateView, self).get_context_data(**kwargs)
- context['image'] = self.get_object()
- return context
-
- def get_initial(self):
- image = self.get_object()
- return {'image_id': self.kwargs['image_id'],
- 'name': image.name,
- 'description': image.properties.get('description', ''),
- 'kernel': image.properties.get('kernel_id', ''),
- 'ramdisk': image.properties.get('ramdisk_id', ''),
- 'architecture': image.properties.get('architecture', ''),
- 'disk_format': image.disk_format,
- 'public': image.is_public,
- 'protected': image.protected}
-
-
-class DetailView(tabs.TabView):
- tab_group_class = ImageDetailTabs
- template_name = 'project/images_and_snapshots/images/detail.html'
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/panel.py b/openstack_dashboard/dashboards/project/images_and_snapshots/panel.py
deleted file mode 100644
index 9746bb82..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/panel.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-# Copyright 2012 OpenStack LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.dashboards.project import dashboard
-
-
-class ImagesAndSnapshots(horizon.Panel):
- name = _("Images & Snapshots")
- slug = 'images_and_snapshots'
-
-
-dashboard.Project.register(ImagesAndSnapshots)
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/__init__.py b/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/forms.py b/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/forms.py
deleted file mode 100644
index 80166e6c..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/forms.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateSnapshot(forms.SelfHandlingForm):
- instance_id = forms.CharField(label=_("Instance ID"),
- widget=forms.HiddenInput(),
- required=False)
- name = forms.CharField(max_length="255", label=_("Snapshot Name"))
-
- def handle(self, request, data):
- try:
- snapshot = api.nova.snapshot_create(request,
- data['instance_id'],
- data['name'])
- # NOTE(gabriel): This API call is only to display a pretty name.
- instance = api.nova.server_get(request, data['instance_id'])
- vals = {"name": data['name'], "inst": instance.name}
- messages.success(request, _('Snapshot "%(name)s" created for '
- 'instance "%(inst)s"') % vals)
- return snapshot
- except:
- redirect = reverse("horizon:project:instances:index")
- exceptions.handle(request,
- _('Unable to create snapshot.'),
- redirect=redirect)
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/tests.py b/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/tests.py
deleted file mode 100644
index 55982dd5..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/tests.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-INDEX_URL = reverse('horizon:project:images_and_snapshots:index')
-
-
-class SnapshotsViewTests(test.TestCase):
- def test_create_snapshot_get(self):
- server = self.servers.first()
- self.mox.StubOutWithMock(api.nova, 'server_get')
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:images_and_snapshots:snapshots:create',
- args=[server.id])
- res = self.client.get(url)
- self.assertTemplateUsed(res,
- 'project/images_and_snapshots/snapshots/create.html')
-
- def test_create_get_server_exception(self):
- server = self.servers.first()
- self.mox.StubOutWithMock(api.nova, 'server_get')
- api.nova.server_get(IsA(http.HttpRequest), server.id) \
- .AndRaise(self.exceptions.nova)
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:images_and_snapshots:snapshots:create',
- args=[server.id])
- res = self.client.get(url)
- redirect = reverse("horizon:project:instances:index")
- self.assertRedirectsNoFollow(res, redirect)
-
- def test_create_snapshot_post(self):
- server = self.servers.first()
- snapshot = self.snapshots.first()
-
- self.mox.StubOutWithMock(api.nova, 'server_get')
- self.mox.StubOutWithMock(api.nova, 'snapshot_create')
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
- api.nova.snapshot_create(IsA(http.HttpRequest), server.id,
- snapshot.name).AndReturn(snapshot)
- self.mox.ReplayAll()
-
- formData = {'method': 'CreateSnapshot',
- 'tenant_id': self.tenant.id,
- 'instance_id': server.id,
- 'name': snapshot.name}
- url = reverse('horizon:project:images_and_snapshots:snapshots:create',
- args=[server.id])
- res = self.client.post(url, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_create_snapshot_post_exception(self):
- server = self.servers.first()
- snapshot = self.snapshots.first()
-
- self.mox.StubOutWithMock(api.nova, 'server_get')
- self.mox.StubOutWithMock(api.nova, 'snapshot_create')
- api.nova.snapshot_create(IsA(http.HttpRequest), server.id,
- snapshot.name).AndRaise(self.exceptions.nova)
- self.mox.ReplayAll()
-
- formData = {'method': 'CreateSnapshot',
- 'tenant_id': self.tenant.id,
- 'instance_id': server.id,
- 'name': snapshot.name}
- url = reverse('horizon:project:images_and_snapshots:snapshots:create',
- args=[server.id])
- res = self.client.post(url, formData)
- redirect = reverse("horizon:project:instances:index")
- self.assertRedirectsNoFollow(res, redirect)
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/urls.py b/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/urls.py
deleted file mode 100644
index b7bf675d..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/urls.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.images_and_snapshots.\
- snapshots.views import CreateView
-
-
-urlpatterns = patterns('',
- url(r'^(?P<instance_id>[^/]+)/create',
- CreateView.as_view(),
- name='create')
-)
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/views.py b/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/views.py
deleted file mode 100644
index 2130dcda..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/snapshots/views.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing instance snapshots.
-"""
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.project.images_and_snapshots.\
- snapshots.forms import CreateSnapshot
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateSnapshot
- template_name = 'project/images_and_snapshots/snapshots/create.html'
- success_url = reverse_lazy("horizon:project:images_and_snapshots:index")
-
- def get_object(self):
- if not hasattr(self, "_object"):
- try:
- self._object = api.nova.server_get(self.request,
- self.kwargs["instance_id"])
- except:
- redirect = reverse('horizon:project:instances:index')
- exceptions.handle(self.request,
- _("Unable to retrieve instance."),
- redirect=redirect)
- return self._object
-
- def get_initial(self):
- return {"instance_id": self.kwargs["instance_id"]}
-
- def get_context_data(self, **kwargs):
- context = super(CreateView, self).get_context_data(**kwargs)
- context['instance'] = self.get_object()
- return context
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html b/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html
deleted file mode 100644
index 1da4cd4f..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_image_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:images_and_snapshots:images:create' %}{% endblock %}
-{% block form_attrs %}enctype="multipart/form-data"{% endblock %}
-
-{% block modal-header %}{% trans "Create An Image" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>
- {% trans "Specify an image to upload to the Image Service." %}
- </p>
- <p>
- {% trans "Currently only images available via an HTTP URL are supported. The image location must be accessible to the Image Service. Compressed image binaries are supported (.zip and .tar.gz.)" %}
- </p>
- <p>
- <strong>{% trans "Please note: " %}</strong>
- {% trans "The Image Location field MUST be a valid and direct URL to the image binary. URLs that redirect or serve error pages will result in unusable images." %}
- </p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Image" %}" />
- <a href="{% url 'horizon:project:images_and_snapshots:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html b/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html
deleted file mode 100644
index e848ac87..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html
+++ /dev/null
@@ -1,82 +0,0 @@
-{% load i18n sizeformat %}
-
-<h3>{% trans "Image Overview" %}</h3>
-
-<div class="info row-fluid detail">
- <h4>{% trans "Info" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Name" %}</dt>
- <dd>{{ image.name|default:_("None") }}</dd>
- {% if image.properties.description %}
- <dt>{% trans "Description" %}</dt>
- <dd>{{ image.properties.description }}</dd>
- {% endif %}
- <dt>{% trans "ID" %}</dt>
- <dd>{{ image.id|default:_("None") }}</dd>
- <dt>{% trans "Status" %}</dt>
- <dd>{{ image.status|default:_("Unknown")|title }}</dd>
- <dt>{% trans "Public" %}</dt>
- <dd>{{ image.is_public }}</dd>
- <dt>{% trans "Protected" %}</dt>
- <dd>{{ image.protected }}</dd>
- <dt>{% trans "Checksum" %}</dt>
- <dd>{{ image.checksum }}</dd>
- <dt>{% trans "Created" %}</dt>
- <dd>{{ image.created_at|default:_("Unknown") }}</dd>
- <dt>{% trans "Updated" %}</dt>
- <dd>{{ image.updated_at|default:_("Never updated") }}</dd>
- </dl>
-</div>
-
-<div class="specs row-fluid detail">
- <h4>{% trans "Specs" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Size" %}</dt>
- <dd>{{ image.size|filesizeformat }}</dd>
- <dt>{% trans "Container Format" %}</dt>
- <dd>{{ image.container_format|default:_("None")|upper }}</dd>
- <dt>{% trans "Disk Format" %}</dt>
- <dd>{{ image.disk_format|default:_("None")|upper }}</dd>
- {% if image.min_disk %}
- <dt>{% trans "Min Disk" %}</dt>
- <dd>{{ image.min_disk|diskgbformat }}</dd>
- {% endif %}
- {% if image.min_ram %}
- <dt>{% trans "Min RAM" %}</dt>
- <dd>{{ image.min_ram|mbformat }}</dd>
- {% endif %}
- </dl>
-</div>
-
-<div class="properties row-fluid detail">
- <h4>{% trans "Custom Properties" %}</h4>
- <hr class="header_rule">
- <dl>
- {% if image.properties.architecture %}
- <dt>{% trans "Architecture" %}</dt>
- <dd>{{ image.properties.architecture }}</dd>
- {% endif %}
- {% if image.properties.kernel_id %}
- <dt>{% trans "Kernel ID" %}</dt>
- <dd>{{ image.properties.kernel_id }}</dd>
- {% endif %}
- {% if image.properties.ramdisk_id %}
- <dt>{% trans "Ramdisk ID" %}</dt>
- <dd>{{ image.properties.ramdisk_id }}</dd>
- {% endif %}
- {% if image.properties.image_state %}
- <dt>{% trans "Euca2ools state" %}</dt>
- <dd>{{ image.properties.image_state }}</dd>
- {% endif %}
- {% if image.properties.project_id %}
- <dt>{% trans "Project ID" %}</dt>
- <dd>{{ image.properties.project_id }}</dd>
- {% endif %}
- {% if image.properties.image_type %}
- <dt>{% trans "Image Type" %}</dt>
- <dd>{{ image.properties.image_type }}</dd>
- {% endif %}
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html b/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html
deleted file mode 100644
index 24e0c162..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_image_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:images_and_snapshots:images:update' image.id %}{% endblock %}
-
-{% block modal-header %}{% trans "Update Image" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "From here you can modify different properties of an image." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Update Image" %}" />
- <a href="{% url 'horizon:project:images_and_snapshots:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html b/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html
deleted file mode 100644
index e8f92f7f..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create An Image" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create An Image") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/images_and_snapshots/images/_create.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html b/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html
deleted file mode 100644
index 17aeb48d..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-
-{% block title %}{% trans "Image Detail "%}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title="Image Detail" %}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html b/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html
deleted file mode 100644
index 604898b8..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Update Image" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Update Image") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/images_and_snapshots/images/_update.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html b/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html
deleted file mode 100644
index 6e9667eb..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Images &amp; Snapshots" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Images &amp; Snapshots") %}
-{% endblock page_header %}
-
-{% block main %}
- <div class="images">
- {{ images_table.render }}
- </div>
- <div class="volume_snapshots">
- {{ volume_snapshots_table.render }}
- </div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html b/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html
deleted file mode 100644
index 99d89488..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_snapshot_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:images_and_snapshots:snapshots:create' instance.id %}{% endblock %}
-
-{% block modal_id %}create_snapshot_modal{% endblock %}
-{% block modal-header %}{% trans "Create Snapshot" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "Snapshots preserve the disk state of a running instance." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Snapshot" %}" />
- <a href="{% url 'horizon:project:images_and_snapshots:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html b/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html
deleted file mode 100644
index 484bd0e3..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html
+++ /dev/null
@@ -1,42 +0,0 @@
-{% load i18n sizeformat parse_date %}
-{% load url from future %}
-
-<h3>{{snapshot.display_name }}</h3>
-
-<div class="info row-fluid detail">
- <h4>{% trans "Info" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Name" %}</dt>
- <dd>{{ snapshot.display_name }}</dd>
- <dt>{% trans "ID" %}</dt>
- <dd>{{ snapshot.id }}</dd>
- {% if snapshot.display_description %}
- <dt>{% trans "Description" %}</dt>
- <dd>{{ snapshot.display_description }}</dd>
- {% endif %}
- <dt>{% trans "Status" %}</dt>
- <dd>{{ snapshot.status|capfirst }}</dd>
- <dt>{% trans "Volume" %}</dt>
- <dd>
- <a href="{% url 'horizon:project:volumes:detail' snapshot.volume_id %}">
- {% if volume.display_name %}
- {{ volume.display_name }}
- {% else %}
- {{ snapshot.volume_id }}
- {% endif %}
- </a>
- </dd>
- </dl>
-</div>
-
-<div class="specs row-fluid detail">
- <h4>{% trans "Specs" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Size" %}</dt>
- <dd>{{ snapshot.size }} {% trans "GB" %}</dd>
- <dt>{% trans "Created" %}</dt>
- <dd>{{ snapshot.created_at|parse_date }}</dd>
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html b/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html
deleted file mode 100644
index 51c7d4b5..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Snapshot" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create a Snapshot") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/images_and_snapshots/snapshots/_create.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html b/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html
deleted file mode 100644
index 72d8dc66..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Volume Snapshot Details" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Volume Snapshot Detail") %}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/tests.py b/openstack_dashboard/dashboards/project/images_and_snapshots/tests.py
deleted file mode 100644
index ed10d44d..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/tests.py
+++ /dev/null
@@ -1,174 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-# Copyright 2012 OpenStack LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-INDEX_URL = reverse('horizon:project:images_and_snapshots:index')
-
-
-class ImagesAndSnapshotsTests(test.TestCase):
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.cinder: ('volume_snapshot_list', 'volume_get')})
- def test_index(self):
- images = self.images.list()
- volumes = self.volumes.list()
-
- for volume in volumes:
- volume.volume_id = volume.id
- for volume in volumes:
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
- .AndReturn(volume)
- for volume in volumes:
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
- .AndReturn(volume)
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id)
-
- api.cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
- .AndReturn(volumes)
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- marker=None).AndReturn([images, False])
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
- self.assertTemplateUsed(res, 'project/images_and_snapshots/index.html')
- self.assertIn('images_table', res.context)
- images_table = res.context['images_table']
- images = images_table.data
- filter_func = lambda im: im.container_format not in ['aki', 'ari']
- filtered_images = filter(filter_func, images)
- self.assertItemsEqual(images, filtered_images)
-
- self.assertTrue(len(images), 3)
- row_actions = images_table.get_row_actions(images[0])
- self.assertTrue(len(row_actions), 3)
- row_actions = images_table.get_row_actions(images[1])
- self.assertTrue(len(row_actions), 2)
- self.assertTrue('delete_image' not in
- [a.name for a in row_actions])
- row_actions = images_table.get_row_actions(images[2])
- self.assertTrue(len(row_actions), 3)
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.cinder: ('volume_snapshot_list', 'volume_get')})
- def test_index_no_images(self):
- volumes = self.volumes.list()
-
- for volume in volumes:
- volume.volume_id = volume.id
- for volume in volumes:
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
- .AndReturn(volume)
- for volume in volumes:
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
- .AndReturn(volume)
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id)
-
- api.cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
- .AndReturn(volumes)
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- marker=None).AndReturn([(), False])
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
- self.assertTemplateUsed(res, 'project/images_and_snapshots/index.html')
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.cinder: ('volume_snapshot_list', 'volume_get')})
- def test_index_error(self):
- volumes = self.volumes.list()
-
- for volume in volumes:
- volume.volume_id = volume.id
- for volume in volumes:
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
- .AndReturn(volume)
- for volume in volumes:
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
- .AndReturn(volume)
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id)
-
- api.cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
- .AndReturn(volumes)
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- marker=None) \
- .AndRaise(self.exceptions.glance)
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
- self.assertTemplateUsed(res, 'project/images_and_snapshots/index.html')
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.cinder: ('volume_snapshot_list', 'volume_get')})
- def test_snapshot_actions(self):
- snapshots = self.snapshots.list()
- volumes = self.volumes.list()
-
- for volume in volumes:
- volume.volume_id = volume.id
- for volume in volumes:
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
- .AndReturn(volume)
- for volume in volumes:
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
- .AndReturn(volume)
- api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id)
-
- api.cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
- .AndReturn(volumes)
- api.glance.image_list_detailed(IsA(http.HttpRequest), marker=None) \
- .AndReturn([snapshots, False])
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
- self.assertTemplateUsed(res, 'project/images_and_snapshots/index.html')
- self.assertIn('images_table', res.context)
- snaps = res.context['images_table']
- self.assertEqual(len(snaps.get_rows()), 3)
-
- row_actions = snaps.get_row_actions(snaps.data[0])
-
- # first instance - status active, owned
- self.assertEqual(len(row_actions), 4)
- self.assertEqual(row_actions[0].verbose_name, u"Launch")
- self.assertEqual(row_actions[1].verbose_name, u"Create Volume")
- self.assertEqual(row_actions[2].verbose_name, u"Edit")
- self.assertEqual(row_actions[3].verbose_name, u"Delete Image")
-
- row_actions = snaps.get_row_actions(snaps.data[1])
-
- # second instance - status active, not owned
- self.assertEqual(len(row_actions), 2)
- self.assertEqual(row_actions[0].verbose_name, u"Launch")
- self.assertEqual(row_actions[1].verbose_name, u"Create Volume")
-
- row_actions = snaps.get_row_actions(snaps.data[2])
- # third instance - status queued, only delete is available
- self.assertEqual(len(row_actions), 1)
- self.assertEqual(unicode(row_actions[0].verbose_name),
- u"Delete Image")
- self.assertEqual(str(row_actions[0]), "<DeleteImage: delete>")
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/urls.py b/openstack_dashboard/dashboards/project/images_and_snapshots/urls.py
deleted file mode 100644
index 2e2b4cd6..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/urls.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import include
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.images_and_snapshots.images \
- import urls as image_urls
-from openstack_dashboard.dashboards.project.images_and_snapshots.snapshots \
- import urls as snapshot_urls
-from openstack_dashboard.dashboards.project.images_and_snapshots.views \
- import DetailView
-from openstack_dashboard.dashboards.project.images_and_snapshots.views \
- import IndexView
-
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'', include(image_urls, namespace='images')),
- url(r'', include(snapshot_urls, namespace='snapshots')),
- url(r'^snapshots/(?P<snapshot_id>[^/]+)/$',
- DetailView.as_view(),
- name='detail'),
-)
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/utils.py b/openstack_dashboard/dashboards/project/images_and_snapshots/utils.py
deleted file mode 100644
index 534005a4..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/utils.py
+++ /dev/null
@@ -1,63 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-
-from openstack_dashboard.api import glance
-
-
-def get_available_images(request, project_id=None, images_cache=None):
- """
- Returns a list of images that are public or owned by the given
- project_id. If project_id is not specified, only public images
- are returned.
-
- :param images_cache:
- An optional dict-like object in which to
- cache public and per-project id image metadata.
- """
- if images_cache is None:
- images_cache = {}
- public_images = images_cache.get('public_images', [])
- images_by_project = images_cache.get('images_by_project', {})
- if 'public_images' not in images_cache:
- public = {"is_public": True,
- "status": "active"}
- try:
- images, _more = glance.image_list_detailed(
- request, filters=public)
- [public_images.append(image) for image in images]
- images_cache['public_images'] = public_images
- except:
- exceptions.handle(request,
- _("Unable to retrieve public images."))
-
- # Preempt if we don't have a project_id yet.
- if project_id is None:
- images_by_project[project_id] = []
-
- if project_id not in images_by_project:
- owner = {"property-owner_id": project_id,
- "status": "active"}
- try:
- owned_images, _more = glance.image_list_detailed(
- request, filters=owner)
- except:
- exceptions.handle(request,
- _("Unable to retrieve images for "
- "the current project."))
- images_by_project[project_id] = owned_images
- if 'images_by_project' not in images_cache:
- images_cache['images_by_project'] = images_by_project
-
- owned_images = images_by_project[project_id]
- images = owned_images + public_images
-
- # Remove duplicate images
- image_ids = []
- final_images = []
- for image in images:
- if image.id not in image_ids:
- image_ids.append(image.id)
- final_images.append(image)
- return [image for image in final_images
- if image.container_format not in ('aki', 'ari')]
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/views.py b/openstack_dashboard/dashboards/project/images_and_snapshots/views.py
deleted file mode 100644
index b146a90c..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/views.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-# Copyright 2012 OpenStack LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing Images and Snapshots.
-"""
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-from horizon import tabs
-
-from openstack_dashboard import api
-from openstack_dashboard.api.base import is_service_enabled
-
-from openstack_dashboard.dashboards.project.images_and_snapshots.\
- images.tables import ImagesTable
-from openstack_dashboard.dashboards.project.images_and_snapshots.\
- volume_snapshots.tables import VolumeSnapshotsTable
-from openstack_dashboard.dashboards.project.images_and_snapshots.\
- volume_snapshots.tabs import SnapshotDetailTabs
-
-LOG = logging.getLogger(__name__)
-
-
-class IndexView(tables.MultiTableView):
- table_classes = (ImagesTable, VolumeSnapshotsTable)
- template_name = 'project/images_and_snapshots/index.html'
-
- def has_more_data(self, table):
- return getattr(self, "_more_%s" % table.name, False)
-
- def get_images_data(self):
- marker = self.request.GET.get(ImagesTable._meta.pagination_param, None)
- try:
- # FIXME(gabriel): The paging is going to be strange here due to
- # our filtering after the fact.
- (all_images,
- self._more_images) = api.glance.image_list_detailed(self.request,
- marker=marker)
- images = [im for im in all_images
- if im.container_format not in ['aki', 'ari']]
- except:
- images = []
- exceptions.handle(self.request, _("Unable to retrieve images."))
- return images
-
- def get_volume_snapshots_data(self):
- if is_service_enabled(self.request, 'volume'):
- try:
- snapshots = api.cinder.volume_snapshot_list(self.request)
- except:
- snapshots = []
- exceptions.handle(self.request, _("Unable to retrieve "
- "volume snapshots."))
- else:
- snapshots = []
- return snapshots
-
-
-class DetailView(tabs.TabView):
- tab_group_class = SnapshotDetailTabs
- template_name = 'project/images_and_snapshots/snapshots/detail.html'
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/__init__.py b/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tables.py b/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tables.py
deleted file mode 100644
index a3816d49..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tables.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.http import urlencode
-from django.utils import safestring
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-from openstack_dashboard import api
-from openstack_dashboard.api import cinder
-
-from openstack_dashboard.dashboards.project.volumes \
- import tables as volume_tables
-
-
-LOG = logging.getLogger(__name__)
-
-
-class DeleteVolumeSnapshot(tables.DeleteAction):
- data_type_singular = _("Volume Snapshot")
- data_type_plural = _("Volume Snapshots")
- action_past = _("Scheduled deletion of")
-
- def delete(self, request, obj_id):
- api.cinder.volume_snapshot_delete(request, obj_id)
-
-
-class CreateVolumeFromSnapshot(tables.LinkAction):
- name = "create_from_snapshot"
- verbose_name = _("Create Volume")
- url = "horizon:project:volumes:create"
- classes = ("ajax-modal", "btn-camera")
-
- def get_link_url(self, datum):
- base_url = reverse(self.url)
- params = urlencode({"snapshot_id": self.table.get_object_id(datum)})
- return "?".join([base_url, params])
-
- def allowed(self, request, volume=None):
- return volume.status == "available" if volume else False
-
-
-class UpdateRow(tables.Row):
- ajax = True
-
- def get_data(self, request, snapshot_id):
- snapshot = cinder.volume_snapshot_get(request, snapshot_id)
- return snapshot
-
-
-class SnapshotVolumeNameColumn(tables.Column):
- def get_raw_data(self, snapshot):
- request = self.table.request
- volume_name = api.cinder.volume_get(request,
- snapshot.volume_id).display_name
- return safestring.mark_safe(volume_name)
-
- def get_link_url(self, snapshot):
- volume_id = api.cinder.volume_get(self.table.request,
- snapshot.volume_id).id
- return reverse(self.link, args=(volume_id,))
-
-
-class VolumeSnapshotsTable(volume_tables.VolumesTableBase):
- name = tables.Column("display_name",
- verbose_name=_("Name"),
- link="horizon:project:images_and_snapshots:detail")
- volume_name = SnapshotVolumeNameColumn("display_name",
- verbose_name=_("Volume Name"),
- link="horizon:project:volumes:detail")
-
- class Meta:
- name = "volume_snapshots"
- verbose_name = _("Volume Snapshots")
- table_actions = (DeleteVolumeSnapshot,)
- row_actions = (CreateVolumeFromSnapshot, DeleteVolumeSnapshot)
- row_class = UpdateRow
- status_columns = ("status",)
- permissions = ['openstack.services.volume']
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tabs.py b/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tabs.py
deleted file mode 100644
index f756c55d..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tabs.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-
-from openstack_dashboard.api import cinder
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "overview"
- template_name = ("project/images_and_snapshots/snapshots/"
- "_detail_overview.html")
-
- def get_context_data(self, request):
- snapshot_id = self.tab_group.kwargs['snapshot_id']
- try:
- snapshot = cinder.volume_snapshot_get(request, snapshot_id)
- volume = cinder.volume_get(request, snapshot.volume_id)
- volume.display_name = None
- except:
- redirect = reverse('horizon:project:images_and_snapshots:index')
- exceptions.handle(self.request,
- _('Unable to retrieve snapshot details.'),
- redirect=redirect)
- return {'snapshot': snapshot,
- 'volume': volume}
-
-
-class SnapshotDetailTabs(tabs.TabGroup):
- slug = "snapshot_details"
- tabs = (OverviewTab,)
diff --git a/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tests.py b/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tests.py
deleted file mode 100644
index 74b7a180..00000000
--- a/openstack_dashboard/dashboards/project/images_and_snapshots/volume_snapshots/tests.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2011 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django import http
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.api import cinder
-from openstack_dashboard.test import helpers as test
-from openstack_dashboard.usage import quotas
-
-
-INDEX_URL = reverse('horizon:project:images_and_snapshots:index')
-
-
-class VolumeSnapshotsViewTests(test.TestCase):
- @test.create_stubs({quotas: ('tenant_quota_usages',)})
- def test_create_snapshot_get(self):
- volume = self.volumes.first()
- usage = {'gigabytes': {'available': 250},
- 'snapshots': {'available': 6}}
- quotas.tenant_quota_usages(IsA(http.HttpRequest)).AndReturn(usage)
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:create_snapshot',
- args=[volume.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, 'project/volumes/create_snapshot.html')
-
- @test.create_stubs({cinder: ('volume_snapshot_create',)})
- def test_create_snapshot_post(self):
- volume = self.volumes.first()
- snapshot = self.volume_snapshots.first()
-
- cinder.volume_snapshot_create(IsA(http.HttpRequest),
- volume.id,
- snapshot.display_name,
- snapshot.display_description) \
- .AndReturn(snapshot)
- self.mox.ReplayAll()
-
- formData = {'method': 'CreateSnapshotForm',
- 'tenant_id': self.tenant.id,
- 'volume_id': volume.id,
- 'name': snapshot.display_name,
- 'description': snapshot.display_description}
- url = reverse('horizon:project:volumes:create_snapshot',
- args=[volume.id])
- res = self.client.post(url, formData)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.cinder: ('volume_snapshot_list',
- 'volume_snapshot_delete')})
- def test_delete_volume_snapshot(self):
- vol_snapshots = self.volume_snapshots.list()
- snapshot = self.volume_snapshots.first()
-
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- marker=None).AndReturn(([], False))
- api.cinder.volume_snapshot_list(IsA(http.HttpRequest)). \
- AndReturn(vol_snapshots)
- api.cinder.volume_snapshot_delete(IsA(http.HttpRequest), snapshot.id)
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- marker=None).AndReturn(([], False))
- api.cinder.volume_snapshot_list(IsA(http.HttpRequest)). \
- AndReturn([])
- self.mox.ReplayAll()
-
- formData = {'action':
- 'volume_snapshots__delete__%s' % snapshot.id}
- res = self.client.post(INDEX_URL, formData, follow=True)
-
- self.assertIn("Scheduled deletion of Volume Snapshot: test snapshot",
- [m.message for m in res.context['messages']])
diff --git a/openstack_dashboard/dashboards/project/instances/__init__.py b/openstack_dashboard/dashboards/project/instances/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/instances/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/instances/panel.py b/openstack_dashboard/dashboards/project/instances/panel.py
deleted file mode 100644
index c204973e..00000000
--- a/openstack_dashboard/dashboards/project/instances/panel.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.project import dashboard
-
-
-class Instances(horizon.Panel):
- name = _("Instances")
- slug = 'instances'
-
-
-dashboard.Project.register(Instances)
diff --git a/openstack_dashboard/dashboards/project/instances/tables.py b/openstack_dashboard/dashboards/project/instances/tables.py
deleted file mode 100644
index b3e932a6..00000000
--- a/openstack_dashboard/dashboards/project/instances/tables.py
+++ /dev/null
@@ -1,575 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-from django.core import urlresolvers
-from django import shortcuts
-from django import template
-from django.template.defaultfilters import timesince
-from django.template.defaultfilters import title
-from django.utils.http import urlencode
-from django.utils.translation import string_concat
-from django.utils.translation import ugettext_lazy as _
-
-from horizon.conf import HORIZON_CONFIG
-from horizon import exceptions
-from horizon import messages
-from horizon import tables
-from horizon.templatetags import sizeformat
-from horizon.utils.filters import parse_isotime
-from horizon.utils.filters import replace_underscores
-
-import logging
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.access_and_security \
- .floating_ips.workflows import IPAssociationWorkflow
-from openstack_dashboard.dashboards.project.instances.tabs import ConsoleTab
-from openstack_dashboard.dashboards.project.instances.tabs import \
- InstanceDetailTabs
-from openstack_dashboard.dashboards.project.instances.tabs import LogTab
-
-from novaclient.v1_1.servers import REBOOT_HARD
-from novaclient.v1_1.servers import REBOOT_SOFT
-
-
-LOG = logging.getLogger(__name__)
-
-ACTIVE_STATES = ("ACTIVE",)
-SNAPSHOT_READY_STATES = ("ACTIVE", "SHUTOFF")
-
-POWER_STATES = {
- 0: "NO STATE",
- 1: "RUNNING",
- 2: "BLOCKED",
- 3: "PAUSED",
- 4: "SHUTDOWN",
- 5: "SHUTOFF",
- 6: "CRASHED",
- 7: "SUSPENDED",
- 8: "FAILED",
- 9: "BUILDING",
-}
-
-PAUSE = 0
-UNPAUSE = 1
-SUSPEND = 0
-RESUME = 1
-
-
-def is_deleting(instance):
- task_state = getattr(instance, "OS-EXT-STS:task_state", None)
- if not task_state:
- return False
- return task_state.lower() == "deleting"
-
-
-class TerminateInstance(tables.BatchAction):
- name = "terminate"
- action_present = _("Terminate")
- action_past = _("Scheduled termination of")
- data_type_singular = _("Instance")
- data_type_plural = _("Instances")
- classes = ('btn-danger', 'btn-terminate')
-
- def allowed(self, request, instance=None):
- return True
-
- def action(self, request, obj_id):
- api.nova.server_delete(request, obj_id)
-
-
-class RebootInstance(tables.BatchAction):
- name = "reboot"
- action_present = _("Hard Reboot")
- action_past = _("Hard Rebooted")
- data_type_singular = _("Instance")
- data_type_plural = _("Instances")
- classes = ('btn-danger', 'btn-reboot')
-
- def allowed(self, request, instance=None):
- return ((instance.status in ACTIVE_STATES
- or instance.status == 'SHUTOFF')
- and not is_deleting(instance))
-
- def action(self, request, obj_id):
- api.nova.server_reboot(request, obj_id, REBOOT_HARD)
-
-
-class SoftRebootInstance(RebootInstance):
- name = "soft_reboot"
- action_present = _("Soft Reboot")
- action_past = _("Soft Rebooted")
-
- def action(self, request, obj_id):
- api.nova.server_reboot(request, obj_id, REBOOT_SOFT)
-
-
-class TogglePause(tables.BatchAction):
- name = "pause"
- action_present = (_("Pause"), _("Resume"))
- action_past = (_("Paused"), _("Resumed"))
- data_type_singular = _("Instance")
- data_type_plural = _("Instances")
- classes = ("btn-pause",)
-
- def allowed(self, request, instance=None):
- if not api.nova.extension_supported('AdminActions',
- request):
- return False
- self.paused = False
- if not instance:
- return self.paused
- self.paused = instance.status == "PAUSED"
- if self.paused:
- self.current_present_action = UNPAUSE
- else:
- self.current_present_action = PAUSE
- return ((instance.status in ACTIVE_STATES or self.paused)
- and not is_deleting(instance))
-
- def action(self, request, obj_id):
- if self.paused:
- api.nova.server_unpause(request, obj_id)
- self.current_past_action = UNPAUSE
- else:
- api.nova.server_pause(request, obj_id)
- self.current_past_action = PAUSE
-
-
-class ToggleSuspend(tables.BatchAction):
- name = "suspend"
- action_present = (_("Suspend"), _("Resume"))
- action_past = (_("Suspended"), _("Resumed"))
- data_type_singular = _("Instance")
- data_type_plural = _("Instances")
- classes = ("btn-suspend",)
-
- def allowed(self, request, instance=None):
- if not api.nova.extension_supported('AdminActions',
- request):
- return False
- self.suspended = False
- if not instance:
- self.suspended
- self.suspended = instance.status == "SUSPENDED"
- if self.suspended:
- self.current_present_action = RESUME
- else:
- self.current_present_action = SUSPEND
- return ((instance.status in ACTIVE_STATES or self.suspended)
- and not is_deleting(instance))
-
- def action(self, request, obj_id):
- if self.suspended:
- api.nova.server_resume(request, obj_id)
- self.current_past_action = RESUME
- else:
- api.nova.server_suspend(request, obj_id)
- self.current_past_action = SUSPEND
-
-
-class LaunchLink(tables.LinkAction):
- name = "launch"
- verbose_name = _("Launch Instance")
- url = "horizon:project:instances:launch"
- classes = ("btn-launch", "ajax-modal")
-
- def allowed(self, request, datum):
- try:
- limits = api.nova.tenant_absolute_limits(request, reserved=True)
-
- instances_available = limits['maxTotalInstances'] \
- - limits['totalInstancesUsed']
- cores_available = limits['maxTotalCores'] \
- - limits['totalCoresUsed']
- ram_available = limits['maxTotalRAMSize'] - limits['totalRAMUsed']
-
- if instances_available <= 0 or cores_available <= 0 \
- or ram_available <= 0:
- if "disabled" not in self.classes:
- self.classes = [c for c in self.classes] + ['disabled']
- self.verbose_name = string_concat(self.verbose_name, ' ',
- _("(Quota exceeded)"))
- else:
- self.verbose_name = _("Launch Instance")
- classes = [c for c in self.classes if c != "disabled"]
- self.classes = classes
- except:
- LOG.exception("Failed to retrieve quota information")
- # If we can't get the quota information, leave it to the
- # API to check when launching
-
- return True # The action should always be displayed
-
-
-class EditInstance(tables.LinkAction):
- name = "edit"
- verbose_name = _("Edit Instance")
- url = "horizon:project:instances:update"
- classes = ("ajax-modal", "btn-edit")
-
- def get_link_url(self, project):
- return self._get_link_url(project, 'instance_info')
-
- def _get_link_url(self, project, step_slug):
- base_url = urlresolvers.reverse(self.url, args=[project.id])
- param = urlencode({"step": step_slug})
- return "?".join([base_url, param])
-
- def allowed(self, request, instance):
- return not is_deleting(instance)
-
-
-class EditInstanceSecurityGroups(EditInstance):
- name = "edit_secgroups"
- verbose_name = _("Edit Security Groups")
-
- def get_link_url(self, project):
- return self._get_link_url(project, 'update_security_groups')
-
- def allowed(self, request, instance=None):
- return (instance.status in ACTIVE_STATES and
- not is_deleting(instance) and
- request.user.tenant_id == instance.tenant_id)
-
-
-class CreateSnapshot(tables.LinkAction):
- name = "snapshot"
- verbose_name = _("Create Snapshot")
- url = "horizon:project:images_and_snapshots:snapshots:create"
- classes = ("ajax-modal", "btn-camera")
-
- def allowed(self, request, instance=None):
- return instance.status in SNAPSHOT_READY_STATES \
- and not is_deleting(instance)
-
-
-class ConsoleLink(tables.LinkAction):
- name = "console"
- verbose_name = _("Console")
- url = "horizon:project:instances:detail"
- classes = ("btn-console",)
-
- def allowed(self, request, instance=None):
- return instance.status in ACTIVE_STATES and not is_deleting(instance)
-
- def get_link_url(self, datum):
- base_url = super(ConsoleLink, self).get_link_url(datum)
- tab_query_string = ConsoleTab(InstanceDetailTabs).get_query_string()
- return "?".join([base_url, tab_query_string])
-
-
-class LogLink(tables.LinkAction):
- name = "log"
- verbose_name = _("View Log")
- url = "horizon:project:instances:detail"
- classes = ("btn-log",)
-
- def allowed(self, request, instance=None):
- return instance.status in ACTIVE_STATES and not is_deleting(instance)
-
- def get_link_url(self, datum):
- base_url = super(LogLink, self).get_link_url(datum)
- tab_query_string = LogTab(InstanceDetailTabs).get_query_string()
- return "?".join([base_url, tab_query_string])
-
-
-class ResizeLink(tables.LinkAction):
- name = "resize"
- verbose_name = _("Resize Instance")
- url = "horizon:project:instances:resize"
- classes = ("ajax-modal", "btn-resize")
-
- def get_link_url(self, project):
- return self._get_link_url(project, 'flavor_choice')
-
- def _get_link_url(self, project, step_slug):
- base_url = urlresolvers.reverse(self.url, args=[project.id])
- param = urlencode({"step": step_slug})
- return "?".join([base_url, param])
-
- def allowed(self, request, instance):
- return ((instance.status in ACTIVE_STATES
- or instance.status == 'SHUTOFF')
- and not is_deleting(instance))
-
-
-class ConfirmResize(tables.Action):
- name = "confirm"
- verbose_name = _("Confirm Resize/Migrate")
- classes = ("btn-confirm", "btn-action-required")
-
- def allowed(self, request, instance):
- return instance.status == 'VERIFY_RESIZE'
-
- def single(self, table, request, instance):
- api.nova.server_confirm_resize(request, instance)
-
-
-class RevertResize(tables.Action):
- name = "revert"
- verbose_name = _("Revert Resize/Migrate")
- classes = ("btn-revert", "btn-action-required")
-
- def allowed(self, request, instance):
- return instance.status == 'VERIFY_RESIZE'
-
- def single(self, table, request, instance):
- api.nova.server_revert_resize(request, instance)
-
-
-class AssociateIP(tables.LinkAction):
- name = "associate"
- verbose_name = _("Associate Floating IP")
- url = "horizon:project:access_and_security:floating_ips:associate"
- classes = ("ajax-modal", "btn-associate")
-
- def allowed(self, request, instance):
- fip = api.network.NetworkClient(request).floating_ips
- if fip.is_simple_associate_supported():
- return False
- return not is_deleting(instance)
-
- def get_link_url(self, datum):
- base_url = urlresolvers.reverse(self.url)
- next = urlresolvers.reverse("horizon:project:instances:index")
- params = {"instance_id": self.table.get_object_id(datum),
- IPAssociationWorkflow.redirect_param_name: next}
- params = urlencode(params)
- return "?".join([base_url, params])
-
-
-class SimpleAssociateIP(tables.Action):
- name = "associate-simple"
- verbose_name = _("Associate Floating IP")
- classes = ("btn-associate-simple",)
-
- def allowed(self, request, instance):
- fip = api.network.NetworkClient(request).floating_ips
- if not fip.is_simple_associate_supported():
- return False
- return not is_deleting(instance)
-
- def single(self, table, request, instance_id):
- try:
- # target_id is port_id for Neutron and instance_id for Nova Network
- # (Neutron API wrapper returns a 'portid_fixedip' string)
- target_id = api.network.floating_ip_target_get_by_instance(
- request, instance_id).split('_')[0]
-
- fip = api.network.tenant_floating_ip_allocate(request)
- api.network.floating_ip_associate(request, fip.id, target_id)
- messages.success(request,
- _("Successfully associated floating IP: %s")
- % fip.ip)
- except:
- exceptions.handle(request,
- _("Unable to associate floating IP."))
- return shortcuts.redirect("horizon:project:instances:index")
-
-
-class SimpleDisassociateIP(tables.Action):
- name = "disassociate"
- verbose_name = _("Disassociate Floating IP")
- classes = ("btn-danger", "btn-disassociate",)
-
- def allowed(self, request, instance):
- if not HORIZON_CONFIG["simple_ip_management"]:
- return False
- return not is_deleting(instance)
-
- def single(self, table, request, instance_id):
- try:
- # target_id is port_id for Neutron and instance_id for Nova Network
- # (Neutron API wrapper returns a 'portid_fixedip' string)
- target_id = api.network.floating_ip_target_get_by_instance(
- request, instance_id).split('_')[0]
-
- fips = [fip for fip in api.network.tenant_floating_ip_list(request)
- if fip.port_id == target_id]
- # Removing multiple floating IPs at once doesn't work, so this pops
- # off the first one.
- if fips:
- fip = fips.pop()
- api.network.floating_ip_disassociate(request,
- fip.id, target_id)
- api.network.tenant_floating_ip_release(request, fip.id)
- messages.success(request,
- _("Successfully disassociated "
- "floating IP: %s") % fip.ip)
- else:
- messages.info(request, _("No floating IPs to disassociate."))
- except:
- exceptions.handle(request,
- _("Unable to disassociate floating IP."))
- return shortcuts.redirect("horizon:project:instances:index")
-
-
-class UpdateRow(tables.Row):
- ajax = True
-
- def get_data(self, request, instance_id):
- instance = api.nova.server_get(request, instance_id)
- instance.full_flavor = api.nova.flavor_get(request,
- instance.flavor["id"])
- return instance
-
-
-class StartInstance(tables.BatchAction):
- name = "start"
- action_present = _("Start")
- action_past = _("Started")
- data_type_singular = _("Instance")
- data_type_plural = _("Instances")
-
- def allowed(self, request, instance):
- return instance.status in ("SHUTDOWN", "SHUTOFF", "CRASHED")
-
- def action(self, request, obj_id):
- api.nova.server_start(request, obj_id)
-
-
-class StopInstance(tables.BatchAction):
- name = "stop"
- action_present = _("Shut Off")
- action_past = _("Shut Off")
- data_type_singular = _("Instance")
- data_type_plural = _("Instances")
- classes = ('btn-danger',)
-
- def allowed(self, request, instance):
- return ((get_power_state(instance)
- in ("RUNNING", "PAUSED", "SUSPENDED"))
- and not is_deleting(instance))
-
- def action(self, request, obj_id):
- api.nova.server_stop(request, obj_id)
-
-
-def get_ips(instance):
- template_name = 'project/instances/_instance_ips.html'
- context = {"instance": instance}
- return template.loader.render_to_string(template_name, context)
-
-
-def get_size(instance):
- if hasattr(instance, "full_flavor"):
- size_string = _("%(name)s | %(RAM)s RAM | %(VCPU)s VCPU "
- "| %(disk)s Disk")
- vals = {'name': instance.full_flavor.name,
- 'RAM': sizeformat.mbformat(instance.full_flavor.ram),
- 'VCPU': instance.full_flavor.vcpus,
- 'disk': sizeformat.diskgbformat(instance.full_flavor.disk)}
- return size_string % vals
- return _("Not available")
-
-
-def get_keyname(instance):
- if hasattr(instance, "key_name"):
- keyname = instance.key_name
- return keyname
- return _("Not available")
-
-
-def get_power_state(instance):
- return POWER_STATES.get(getattr(instance, "OS-EXT-STS:power_state", 0), '')
-
-
-STATUS_DISPLAY_CHOICES = (
- ("resize", "Resize/Migrate"),
- ("verify_resize", "Confirm or Revert Resize/Migrate"),
- ("revert_resize", "Revert Resize/Migrate"),
-)
-
-
-TASK_DISPLAY_CHOICES = (
- ("image_snapshot", "Snapshotting"),
- ("resize_prep", "Preparing Resize or Migrate"),
- ("resize_migrating", "Resizing or Migrating"),
- ("resize_migrated", "Resized or Migrated"),
- ("resize_finish", "Finishing Resize or Migrate"),
- ("resize_confirming", "Confirming Resize or Nigrate"),
- ("resize_reverting", "Reverting Resize or Migrate"),
- ("unpausing", "Resuming"),
-)
-
-
-class InstancesFilterAction(tables.FilterAction):
-
- def filter(self, table, instances, filter_string):
- """ Naive case-insensitive search. """
- q = filter_string.lower()
- return [instance for instance in instances
- if q in instance.name.lower()]
-
-
-class InstancesTable(tables.DataTable):
- TASK_STATUS_CHOICES = (
- (None, True),
- ("none", True)
- )
- STATUS_CHOICES = (
- ("active", True),
- ("shutoff", True),
- ("suspended", True),
- ("paused", True),
- ("error", False),
- )
- name = tables.Column("name",
- link=("horizon:project:instances:detail"),
- verbose_name=_("Instance Name"))
- image_name = tables.Column("image_name",
- verbose_name=_("Image Name"))
- ip = tables.Column(get_ips,
- verbose_name=_("IP Address"),
- attrs={'data-type': "ip"})
- size = tables.Column(get_size,
- verbose_name=_("Size"),
- attrs={'data-type': 'size'})
- keypair = tables.Column(get_keyname, verbose_name=_("Keypair"))
- status = tables.Column("status",
- filters=(title, replace_underscores),
- verbose_name=_("Status"),
- status=True,
- status_choices=STATUS_CHOICES,
- display_choices=STATUS_DISPLAY_CHOICES)
- task = tables.Column("OS-EXT-STS:task_state",
- verbose_name=_("Task"),
- filters=(title, replace_underscores),
- status=True,
- status_choices=TASK_STATUS_CHOICES,
- display_choices=TASK_DISPLAY_CHOICES)
- state = tables.Column(get_power_state,
- filters=(title, replace_underscores),
- verbose_name=_("Power State"))
- created = tables.Column("created",
- verbose_name=_("Uptime"),
- filters=(parse_isotime, timesince))
-
- class Meta:
- name = "instances"
- verbose_name = _("Instances")
- status_columns = ["status", "task"]
- row_class = UpdateRow
- table_actions = (LaunchLink, TerminateInstance, InstancesFilterAction)
- row_actions = (StartInstance, ConfirmResize, RevertResize,
- CreateSnapshot, SimpleAssociateIP, AssociateIP,
- SimpleDisassociateIP, EditInstance,
- EditInstanceSecurityGroups, ConsoleLink, LogLink,
- TogglePause, ToggleSuspend, ResizeLink,
- SoftRebootInstance, RebootInstance, StopInstance,
- TerminateInstance)
diff --git a/openstack_dashboard/dashboards/project/instances/tabs.py b/openstack_dashboard/dashboards/project/instances/tabs.py
deleted file mode 100644
index 8f4172d9..00000000
--- a/openstack_dashboard/dashboards/project/instances/tabs.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-
-from openstack_dashboard import api
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "overview"
- template_name = ("project/instances/"
- "_detail_overview.html")
-
- def get_context_data(self, request):
- return {"instance": self.tab_group.kwargs['instance']}
-
-
-class LogTab(tabs.Tab):
- name = _("Log")
- slug = "log"
- template_name = "project/instances/_detail_log.html"
- preload = False
-
- def get_context_data(self, request):
- instance = self.tab_group.kwargs['instance']
- try:
- data = api.nova.server_console_output(request,
- instance.id,
- tail_length=35)
- except:
- data = _('Unable to get log for instance "%s".') % instance.id
- exceptions.handle(request, ignore=True)
- return {"instance": instance,
- "console_log": data}
-
-
-class ConsoleTab(tabs.Tab):
- name = _("Console")
- slug = "console"
- template_name = "project/instances/_detail_console.html"
- preload = False
-
- def get_context_data(self, request):
- instance = self.tab_group.kwargs['instance']
- # Currently prefer VNC over SPICE, since noVNC has had much more
- # testing than spice-html5
- console_type = getattr(settings, 'CONSOLE_TYPE', 'AUTO')
- if console_type == 'AUTO':
- try:
- console = api.nova.server_vnc_console(request, instance.id)
- console_url = "%s&title=%s(%s)" % (
- console.url,
- getattr(instance, "name", ""),
- instance.id)
- except:
- try:
- console = api.nova.server_spice_console(request,
- instance.id)
- console_url = "%s&title=%s(%s)" % (
- console.url,
- getattr(instance, "name", ""),
- instance.id)
- except:
- console_url = None
- elif console_type == 'VNC':
- try:
- console = api.nova.server_vnc_console(request, instance.id)
- console_url = "%s&title=%s(%s)" % (
- console.url,
- getattr(instance, "name", ""),
- instance.id)
- except:
- console_url = None
- elif console_type == 'SPICE':
- try:
- console = api.nova.server_spice_console(request, instance.id)
- console_url = "%s&title=%s(%s)" % (
- console.url,
- getattr(instance, "name", ""),
- instance.id)
- except:
- console_url = None
- else:
- console_url = None
-
- return {'console_url': console_url, 'instance_id': instance.id}
-
-
-class InstanceDetailTabs(tabs.TabGroup):
- slug = "instance_details"
- tabs = (OverviewTab, LogTab, ConsoleTab)
- sticky = True
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/_detail_console.html b/openstack_dashboard/dashboards/project/instances/templates/instances/_detail_console.html
deleted file mode 100644
index 2992350b..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/_detail_console.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% load i18n %}
-{% load url from future %}
-
-<h3>{% trans "Instance Console" %}</h3>
-{% if console_url %}
-<p class='alert alert-info'>{% blocktrans %}If console is not responding to keyboard input: click the grey status bar below.{% endblocktrans %} <a href="{{ console_url }}" style="text-decoration: underline">{% trans "Click here to show only console" %}</a></p>
-<iframe id="console_embed" src="{{ console_url }}" style="width:100%;height:100%"></iframe>
-<script type="text/javascript">
- var fix_height = function() {
- $('iframe#console_embed').css({ height: $(document).height() + 'px' });
- };
- // there are two code paths to this particular block; handle them both
- if (typeof($) != 'undefined') {
- $(document).ready(fix_height);
- } else {
- addHorizonLoadEvent(fix_height);
- }
-</script>
-{% else %}
-<p class='alert alert-error'>{% blocktrans %}console is currently unavailable. Please try again later.{% endblocktrans %}
-<a class='btn btn-mini' href="{% url 'horizon:project:instances:detail' instance_id %}">{% trans "Reload" %}</a></p>
-{% endif %}
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/_detail_log.html b/openstack_dashboard/dashboards/project/instances/templates/instances/_detail_log.html
deleted file mode 100644
index bb2525cc..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/_detail_log.html
+++ /dev/null
@@ -1,18 +0,0 @@
-{% load i18n %}
-{% load url from future %}
-
-<div class="clearfix">
- <h3 class="pull-left">{% trans "Instance Console Log" %}</h3>
-
- <form id="tail_length" action="{% url 'horizon:project:instances:console' instance.id %}" class="form-inline pull-right">
- <label for="tail_length_select">{% trans "Log Length" %}</label>
- <input class="span1" type="text" name="length" value="35" />
- <button class="btn btn-small btn-primary" type="submit">{% trans "Go" %}</button>
- {% url 'horizon:project:instances:console' instance.id as console_url %}
- <a class="btn btn-small" target="_blank" href="{{ console_url }}">{% trans "View Full Log" %}</a>
- </form>
-</div>
-
-<pre class="logs">
- {{ console_log }}
-</pre>
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/_detail_overview.html b/openstack_dashboard/dashboards/project/instances/templates/instances/_detail_overview.html
deleted file mode 100644
index 1b1006ff..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/_detail_overview.html
+++ /dev/null
@@ -1,111 +0,0 @@
-{% load i18n sizeformat %}
-{% load url from future %}
-
-<h3>{% trans "Instance Overview" %}</h3>
-
-<div class="status row-fluid detail">
- <h4>{% trans "Info" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Name" %}</dt>
- <dd>{{ instance.name }}</dd>
- <dt>{% trans "ID" %}</dt>
- <dd>{{ instance.id }}</dd>
- <dt>{% trans "Status" %}</dt>
- <dd>{{ instance.status|title }}</dd>
- <dt>{% trans "Created" %}</dt>
- <dd>{{ instance.created|parse_isotime }}</dd>
- <dt>{% trans "Uptime" %}</dt>
- <dd>{{ instance.created|parse_isotime|timesince }}</dd>
- </dl>
-</div>
-
-<div class="specs row-fluid detail">
- <h4>{% trans "Specs" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Flavor" %}</dt>
- <dd>{{ instance.full_flavor.name }}</dd>
- <dt>{% trans "RAM" %}</dt>
- <dd>{{ instance.full_flavor.ram|mbformat }}</dd>
- <dt>{% trans "VCPUs" %}</dt>
- <dd>{{ instance.full_flavor.vcpus }} {% trans "VCPU" %}</dd>
- <dt>{% trans "Disk" %}</dt>
- <dd>{{ instance.full_flavor.disk }}{% trans "GB" %}</dd>
- {% if instance.full_flavor.ephemeral %}
- <dt>{% trans "Ephemeral Disk" %}</dt>
- <dd>{{ instance.full_flavor.ephemeral }}{% trans "GB" %}</dd>
- {% endif %}
- </dl>
-</div>
-
-<div class="addresses row-fluid detail">
- <h4>{% trans "IP Addresses" %}</h4>
- <hr class="header_rule">
- <dl>
- {% for network, ip_list in instance.addresses.items %}
- <dt>{{ network|title }}</dt>
- <dd>
- {% for ip in ip_list %}
- {% if not forloop.last %}{{ ip.addr}},&nbsp;{% else %}{{ip.addr}}{% endif %}
- {% endfor %}
- </dd>
- {% endfor %}
- </dl>
-</div>
-
-<div class="security_groups row-fluid detail">
- <h4>{% trans "Security Groups" %}</h4>
- <hr class="header_rule">
- <dl>
- {% for group in instance.security_groups %}
- <dt>{{ group.name }}</dt>
- <dd>
- <ul>
- {% for rule in group.rules %}
- <li>{{ rule }}</li>
- {% empty %}
- <li><em>{% trans "No rules defined." %}</em></li>
- {% endfor %}
- </ul>
- </dd>
- {% endfor %}
- </dl>
-</div>
-
-<div class="meta row-fluid detail">
- <h4>{% trans "Meta" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Key Name" %}</dt>
- {% with default_key_name="<em>"|add:_("None")|add:"</em>" %}
- <dd>{{ instance.key_name|default:default_key_name }}</dd>
- {% endwith %}
- {% url 'horizon:project:images_and_snapshots:images:detail' instance.image.id as image_url %}
- <dt>{% trans "Image Name" %}</dt>
- <dd><a href="{{ image_url }}">{{ instance.image_name }}</a></dd>
- {% with default_item_value="<em>"|add:_("N/A")|add:"</em>" %}
- {% for key, value in instance.metadata.items %}
- <dt>{{ key|force_escape }}</dt>
- <dd>{{ value|force_escape|default:default_item_value }}</dd>
- {% endfor%}
- {% endwith %}
- </dl>
-</div>
-
-<div class="volumes row-fluid detail">
- <h4>{% trans "Volumes Attached" %}</h4>
- <hr class="header_rule">
- <dl>
- {% for volume in instance.volumes %}
- <dt>{% trans "Attached To" %}</dt>
- <dd>
- <a href="{% url 'horizon:project:volumes:detail' volume.volumeId %}">{{ volume.name }}</a><span> {% trans "on" %} {{ volume.device }}</span>
- </dd>
- {% empty %}
- <dt>{% trans "Volume" %}</dt>
- <dd><em>{% trans "No volumes attached." %}</em></dd>
- {% endfor %}
- </dl>
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/_flavors_and_quotas.html b/openstack_dashboard/dashboards/project/instances/templates/instances/_flavors_and_quotas.html
deleted file mode 100644
index ee546819..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/_flavors_and_quotas.html
+++ /dev/null
@@ -1,50 +0,0 @@
-{% load i18n horizon humanize %}
-
-{% block help_message %}
-{% endblock %}
-
-<h4>{% trans "Flavor Details" %}</h4>
-<table class="flavor_table table-striped">
- <tbody>
- <tr><td class="flavor_name">{% trans "Name" %}</td><td><span id="flavor_name"></span></td></tr>
- <tr><td class="flavor_name">{% trans "VCPUs" %}</td><td><span id="flavor_vcpus"></span></td></tr>
- <tr><td class="flavor_name">{% trans "Root Disk" %}</td><td><span id="flavor_disk"> </span> {% trans "GB" %}</td></tr>
- <tr><td class="flavor_name">{% trans "Ephemeral Disk" %}</td><td><span id="flavor_ephemeral"></span> {% trans "GB" %}</td></tr>
- <tr><td class="flavor_name">{% trans "Total Disk" %}</td><td><span id="flavor_disk_total"></span> {% trans "GB" %}</td></tr>
- <tr><td class="flavor_name">{% trans "RAM" %}</td><td><span id="flavor_ram"></span> {% trans "MB" %}</td></tr>
- </tbody>
-</table>
-
-<div class="quota-dynamic">
- <h4>{% trans "Project Limits" %}</h4>
- <div class="quota_title clearfix">
- <strong>{% trans "Number of Instances" %}</strong>
- {% blocktrans with used=usages.totalInstancesUsed|intcomma quota=usages.maxTotalInstances|intcomma %}<p>{{ used }} of {{ quota }} Used</p>{% endblocktrans %}
- </div>
- <div id="quota_instances" class="quota_bar" data-progress-indicator-flavor data-quota-limit="{{ usages.maxTotalInstances }}" data-quota-used="{{ usages.totalInstancesUsed }}">
- </div>
-
- <div class="quota_title clearfix">
- <strong>{% trans "Number of VCPUs" %}</strong>
- {% blocktrans with used=usages.totalCoresUsed|intcomma quota=usages.maxTotalCores|intcomma %}<p>{{ used }} of {{ quota }} Used</p>{% endblocktrans %}
- </div>
- <div id="quota_vcpus" class="quota_bar" data-progress-indicator-flavor data-quota-limit="{{ usages.maxTotalCores }}" data-quota-used="{{ usages.totalCoresUsed }}">
- </div>
-
- <div class="quota_title clearfix">
- <strong>{% trans "Total RAM" %}</strong>
- {% blocktrans with used=usages.totalRAMUsed|intcomma quota=usages.maxTotalRAMSize|intcomma %}<p>{{ used }} of {{ quota }} MB Used</p>{% endblocktrans %}
- </div>
- <div id="quota_ram" data-progress-indicator-flavor data-quota-limit="{{ usages.maxTotalRAMSize }}" data-quota-used="{{ usages.totalRAMUsed }}" class="quota_bar">
- </div>
-</div>
-
-<script type="text/javascript" charset="utf-8">
- if(typeof horizon.Quota !== 'undefined') {
- horizon.Quota.initWithFlavors({{ flavors|safe|default:"{}" }});
- } else {
- addHorizonLoadEvent(function() {
- horizon.Quota.initWithFlavors({{ flavors|safe|default:"{}" }});
- });
- }
-</script>
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/_instance_ips.html b/openstack_dashboard/dashboards/project/instances/templates/instances/_instance_ips.html
deleted file mode 100644
index 72ed59fe..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/_instance_ips.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{% for ip_group, addresses in instance.addresses.items %}
- {% if instance.addresses.items|length > 1 %}
- <h4>{{ ip_group }}</h4>
- {% endif %}
- <ul>
- {% for address in addresses %}
- <li>{{ address.addr }}</li>
- {% endfor %}
- </ul>
-{% endfor %}
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_customize_help.html b/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_customize_help.html
deleted file mode 100644
index eb947e4b..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_customize_help.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{% load i18n %}
-<p>{% blocktrans %}You can customize your instance after it's launched using the options available here.{% endblocktrans %}</p>
-<p>{% blocktrans %}The "Customization Script" field is analogous to "User Data" in other systems.{% endblocktrans %}</p>
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_details_help.html b/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_details_help.html
deleted file mode 100644
index b05b017f..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_details_help.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends 'project/instances/_flavors_and_quotas.html' %}
-{% load i18n %}
-
-{% block help_message %}
-<p>{% blocktrans %}Specify the details for launching an instance.{% endblocktrans %}</p>
-<p>{% blocktrans %}The chart below shows the resources used by this project in relation to the project's quotas.{% endblocktrans %}</p>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_network_help.html b/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_network_help.html
deleted file mode 100644
index 290b11d0..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_network_help.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{% load i18n horizon %}
-
-<p>{% blocktrans %}Choose network from Available networks to Selected Networks by push button or drag and drop, you may change nic order by drag and drop as well. {% endblocktrans %}</p>
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_volumes_help.html b/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_volumes_help.html
deleted file mode 100644
index 26f4429c..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/_launch_volumes_help.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{% load i18n horizon %}
-
-<p>{% blocktrans %}An instance can be launched with varying types of attached storage. You may select from those options here.{% endblocktrans %}</p>
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/_update_networks.html b/openstack_dashboard/dashboards/project/instances/templates/instances/_update_networks.html
deleted file mode 100644
index 1f635a8d..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/_update_networks.html
+++ /dev/null
@@ -1,46 +0,0 @@
-{% load i18n %}
-
-<noscript><h3>{{ step }}</h3></noscript>
-<table class="table-fixed" id="networkListSortContainer">
- <tbody>
- <tr>
- <td class="actions">
- <h4 id="selected_network_h4">{% trans "Selected Networks" %}</h4>
- <ul id="selected_network" class="networklist">
- </ul>
- <h4>{% trans "Available networks" %}</h4>
- <ul id="available_network" class="networklist">
- </ul>
- </td>
- <td class="help_text">
- {% include "project/instances/_launch_network_help.html" %}
- </td>
- </tr>
- </tbody>
-</table>
-
-<table class="table-fixed" id="networkListIdContainer">
- <tbody>
- <tr>
- <td class="actions">
- <div id="networkListId">
- {% include "horizon/common/_form_fields.html" %}
- </div>
- </td>
- <td class="help_text">
- {{ step.get_help_text }}
- </td>
- </tr>
- </tbody>
-</table>
-
-
-<script>
- if (typeof $ !== 'undefined') {
- horizon.instances.workflow_init($(".workflow"));
- } else {
- addHorizonLoadEvent(function() {
- horizon.instances.workflow_init($(".workflow"));
- });
- }
-</script>
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/detail.html b/openstack_dashboard/dashboards/project/instances/templates/instances/detail.html
deleted file mode 100644
index 82f1e0ee..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/detail.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n sizeformat %}
-{% block title %}{% trans "Instance Detail" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title="Instance Detail: "|add:instance.name %}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/instances/templates/instances/index.html b/openstack_dashboard/dashboards/project/instances/templates/instances/index.html
deleted file mode 100644
index a47f1e5d..00000000
--- a/openstack_dashboard/dashboards/project/instances/templates/instances/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Instances" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Instances") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/instances/tests.py b/openstack_dashboard/dashboards/project/instances/tests.py
deleted file mode 100644
index 0e51d94a..00000000
--- a/openstack_dashboard/dashboards/project/instances/tests.py
+++ /dev/null
@@ -1,1740 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import uuid
-
-from django.core.urlresolvers import reverse
-from django import http
-from django.utils.datastructures import SortedDict
-from django.utils.http import urlencode
-
-from mox import IgnoreArg
-from mox import IsA
-
-from horizon.workflows.views import WorkflowView
-
-from openstack_dashboard import api
-from openstack_dashboard.api import cinder
-from openstack_dashboard.test import helpers as test
-
-from openstack_dashboard.dashboards.project.instances.tables import LaunchLink
-from openstack_dashboard.dashboards.project.instances.tabs \
- import InstanceDetailTabs
-from openstack_dashboard.dashboards.project.instances.workflows \
- import LaunchInstance
-
-from novaclient.v1_1.servers import REBOOT_HARD
-from novaclient.v1_1.servers import REBOOT_SOFT
-
-INDEX_URL = reverse('horizon:project:instances:index')
-
-
-class InstanceTests(test.TestCase):
- @test.create_stubs({api.nova: ('flavor_list',
- 'server_list',
- 'tenant_absolute_limits',
- 'extension_supported',)})
- def test_index(self):
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
- .MultipleTimes().AndReturn(self.limits['absolute'])
-
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
-
- self.assertTemplateUsed(res,
- 'project/instances/index.html')
- instances = res.context['instances_table'].data
-
- self.assertItemsEqual(instances, self.servers.list())
-
- @test.create_stubs({api.nova: ('server_list',
- 'tenant_absolute_limits',)})
- def test_index_server_list_exception(self):
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndRaise(self.exceptions.nova)
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
- .MultipleTimes().AndReturn(self.limits['absolute'])
-
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
-
- self.assertTemplateUsed(res, 'project/instances/index.html')
- self.assertEqual(len(res.context['instances_table'].data), 0)
- self.assertMessageCount(res, error=1)
-
- @test.create_stubs({api.nova: ('flavor_list',
- 'server_list',
- 'flavor_get',
- 'tenant_absolute_limits',
- 'extension_supported',)})
- def test_index_flavor_list_exception(self):
- servers = self.servers.list()
- flavors = self.flavors.list()
- full_flavors = SortedDict([(f.id, f) for f in flavors])
- search_opts = {'marker': None, 'paginate': True}
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([servers, False])
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndRaise(self.exceptions.nova)
- for server in servers:
- api.nova.flavor_get(IsA(http.HttpRequest), server.flavor["id"]). \
- AndReturn(full_flavors[server.flavor["id"]])
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
- .MultipleTimes().AndReturn(self.limits['absolute'])
-
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
-
- self.assertTemplateUsed(res, 'project/instances/index.html')
- instances = res.context['instances_table'].data
-
- self.assertItemsEqual(instances, self.servers.list())
-
- @test.create_stubs({api.nova: ('flavor_list',
- 'server_list',
- 'flavor_get',
- 'tenant_absolute_limits',
- 'extension_supported',)})
- def test_index_flavor_get_exception(self):
- servers = self.servers.list()
- flavors = self.flavors.list()
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- # UUIDs generated using indexes are unlikely to match
- # any of existing flavor ids and are guaranteed to be deterministic.
- for i, server in enumerate(servers):
- server.flavor['id'] = str(uuid.UUID(int=i))
-
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([servers, False])
- api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(flavors)
- for server in servers:
- api.nova.flavor_get(IsA(http.HttpRequest), server.flavor["id"]). \
- AndRaise(self.exceptions.nova)
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
- .MultipleTimes().AndReturn(self.limits['absolute'])
-
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
-
- instances = res.context['instances_table'].data
-
- self.assertTemplateUsed(res, 'project/instances/index.html')
- self.assertMessageCount(res, error=len(servers))
- self.assertItemsEqual(instances, self.servers.list())
-
- @test.create_stubs({api.nova: ('server_list',
- 'flavor_list',
- 'server_delete',)})
- def test_terminate_instance(self):
- server = self.servers.first()
-
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
- api.nova.server_delete(IsA(http.HttpRequest), server.id)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__terminate__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_list',
- 'flavor_list',
- 'server_delete',)})
- def test_terminate_instance_exception(self):
- server = self.servers.first()
-
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
- api.nova.server_delete(IsA(http.HttpRequest), server.id) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__terminate__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_pause',
- 'server_list',
- 'flavor_list',
- 'extension_supported',)})
- def test_pause_instance(self):
- server = self.servers.first()
-
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.server_pause(IsA(http.HttpRequest), server.id)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__pause__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_pause',
- 'server_list',
- 'flavor_list',
- 'extension_supported',)})
- def test_pause_instance_exception(self):
- server = self.servers.first()
-
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.server_pause(IsA(http.HttpRequest), server.id) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__pause__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_unpause',
- 'server_list',
- 'flavor_list',
- 'extension_supported',)})
- def test_unpause_instance(self):
- server = self.servers.first()
- server.status = "PAUSED"
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.server_unpause(IsA(http.HttpRequest), server.id)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__pause__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_unpause',
- 'server_list',
- 'flavor_list',
- 'extension_supported',)})
- def test_unpause_instance_exception(self):
- server = self.servers.first()
- server.status = "PAUSED"
-
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.server_unpause(IsA(http.HttpRequest), server.id) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__pause__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_reboot',
- 'server_list',
- 'flavor_list',)})
- def test_reboot_instance(self):
- server = self.servers.first()
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.server_reboot(IsA(http.HttpRequest), server.id,
- REBOOT_HARD)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__reboot__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_reboot',
- 'server_list',
- 'flavor_list',)})
- def test_reboot_instance_exception(self):
- server = self.servers.first()
-
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.server_reboot(IsA(http.HttpRequest), server.id,
- REBOOT_HARD) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__reboot__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_reboot',
- 'server_list',
- 'flavor_list',)})
- def test_soft_reboot_instance(self):
- server = self.servers.first()
-
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.server_reboot(IsA(http.HttpRequest), server.id,
- REBOOT_SOFT)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__soft_reboot__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_suspend',
- 'server_list',
- 'flavor_list',
- 'extension_supported',)})
- def test_suspend_instance(self):
- server = self.servers.first()
-
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.server_suspend(IsA(http.HttpRequest), unicode(server.id))
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__suspend__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_suspend',
- 'server_list',
- 'flavor_list',
- 'extension_supported',)})
- def test_suspend_instance_exception(self):
- server = self.servers.first()
-
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.server_suspend(IsA(http.HttpRequest), unicode(server.id)) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__suspend__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_resume',
- 'server_list',
- 'flavor_list',
- 'extension_supported',)})
- def test_resume_instance(self):
- server = self.servers.first()
- server.status = "SUSPENDED"
-
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.server_resume(IsA(http.HttpRequest), unicode(server.id))
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__suspend__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_resume',
- 'server_list',
- 'flavor_list',
- 'extension_supported',)})
- def test_resume_instance_exception(self):
- server = self.servers.first()
- server.status = "SUSPENDED"
-
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.server_resume(IsA(http.HttpRequest),
- unicode(server.id)) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__suspend__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ("server_get",
- "instance_volumes_list",
- "flavor_get"),
- api.network: ("server_security_groups",)})
- def test_instance_details_volumes(self):
- server = self.servers.first()
- volumes = [self.volumes.list()[1]]
-
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
- api.nova.instance_volumes_list(IsA(http.HttpRequest),
- server.id).AndReturn(volumes)
- api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
- .AndReturn(self.flavors.first())
- api.network.server_security_groups(IsA(http.HttpRequest), server.id) \
- .AndReturn(self.security_groups.first())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:detail',
- args=[server.id])
- res = self.client.get(url)
-
- self.assertItemsEqual(res.context['instance'].volumes, volumes)
-
- @test.create_stubs({api.nova: ("server_get",
- "instance_volumes_list",
- "flavor_get"),
- api.network: ("server_security_groups",)})
- def test_instance_details_volume_sorting(self):
- server = self.servers.first()
- volumes = self.volumes.list()[1:3]
-
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
- api.nova.instance_volumes_list(IsA(http.HttpRequest),
- server.id).AndReturn(volumes)
- api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
- .AndReturn(self.flavors.first())
- api.network.server_security_groups(IsA(http.HttpRequest), server.id) \
- .AndReturn(self.security_groups.first())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:detail',
- args=[server.id])
- res = self.client.get(url)
-
- self.assertItemsEqual(res.context['instance'].volumes, volumes)
- self.assertEquals(res.context['instance'].volumes[0].device,
- "/dev/hda")
- self.assertEquals(res.context['instance'].volumes[1].device,
- "/dev/hdk")
-
- @test.create_stubs({api.nova: ("server_get",
- "instance_volumes_list",
- "flavor_get"),
- api.network: ("server_security_groups",)})
- def test_instance_details_metadata(self):
- server = self.servers.first()
-
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
- api.nova.instance_volumes_list(IsA(http.HttpRequest),
- server.id).AndReturn([])
- api.nova.flavor_get(IsA(http.HttpRequest), server.flavor['id']) \
- .AndReturn(self.flavors.first())
- api.network.server_security_groups(IsA(http.HttpRequest), server.id) \
- .AndReturn(self.security_groups.list())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:detail',
- args=[server.id])
- tg = InstanceDetailTabs(self.request, instance=server)
- qs = "?%s=%s" % (tg.param_name, tg.get_tab("overview").get_id())
- res = self.client.get(url + qs)
-
- self.assertContains(res, "<dd>keyName</dd>", 1)
- self.assertContains(res, "<dt>someMetaLabel</dt>", 1)
- self.assertContains(res, "<dd>someMetaData</dd>", 1)
- self.assertContains(res, "<dt>some&lt;b&gt;html&lt;/b&gt;label</dt>",
- 1)
- self.assertContains(res, "<dd>&lt;!--</dd>", 1)
- self.assertContains(res, "<dt>empty</dt>", 1)
- self.assertContains(res, "<dd><em>N/A</em></dd>", 1)
-
- @test.create_stubs({api.nova: ('server_console_output',)})
- def test_instance_log(self):
- server = self.servers.first()
- CONSOLE_OUTPUT = 'output'
-
- api.nova.server_console_output(IsA(http.HttpRequest),
- server.id, tail_length=None) \
- .AndReturn(CONSOLE_OUTPUT)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:console',
- args=[server.id])
- tg = InstanceDetailTabs(self.request, instance=server)
- qs = "?%s=%s" % (tg.param_name, tg.get_tab("log").get_id())
- res = self.client.get(url + qs)
-
- self.assertNoMessages()
- self.assertIsInstance(res, http.HttpResponse)
- self.assertContains(res, CONSOLE_OUTPUT)
-
- @test.create_stubs({api.nova: ('server_console_output',)})
- def test_instance_log_exception(self):
- server = self.servers.first()
-
- api.nova.server_console_output(IsA(http.HttpRequest),
- server.id, tail_length=None) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:console',
- args=[server.id])
- tg = InstanceDetailTabs(self.request, instance=server)
- qs = "?%s=%s" % (tg.param_name, tg.get_tab("log").get_id())
- res = self.client.get(url + qs)
-
- self.assertContains(res, "Unable to get log for")
-
- def test_instance_vnc(self):
- server = self.servers.first()
- CONSOLE_OUTPUT = '/vncserver'
-
- console_mock = self.mox.CreateMock(api.nova.VNCConsole)
- console_mock.url = CONSOLE_OUTPUT
-
- self.mox.StubOutWithMock(api.nova, 'server_vnc_console')
- self.mox.StubOutWithMock(api.nova, 'server_get')
- api.nova.server_get(IsA(http.HttpRequest), server.id) \
- .AndReturn(server)
- api.nova.server_vnc_console(IgnoreArg(), server.id) \
- .AndReturn(console_mock)
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:vnc',
- args=[server.id])
- res = self.client.get(url)
- redirect = CONSOLE_OUTPUT + '&title=%s(1)' % server.name
- self.assertRedirectsNoFollow(res, redirect)
-
- @test.create_stubs({api.nova: ('server_vnc_console',)})
- def test_instance_vnc_exception(self):
- server = self.servers.first()
-
- api.nova.server_vnc_console(IsA(http.HttpRequest), server.id) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:vnc',
- args=[server.id])
- res = self.client.get(url)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_instance_spice(self):
- server = self.servers.first()
- CONSOLE_OUTPUT = '/spiceserver'
-
- console_mock = self.mox.CreateMock(api.nova.SPICEConsole)
- console_mock.url = CONSOLE_OUTPUT
-
- self.mox.StubOutWithMock(api.nova, 'server_spice_console')
- self.mox.StubOutWithMock(api.nova, 'server_get')
- api.nova.server_get(IsA(http.HttpRequest), server.id) \
- .AndReturn(server)
- api.nova.server_spice_console(IgnoreArg(), server.id) \
- .AndReturn(console_mock)
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:spice',
- args=[server.id])
- res = self.client.get(url)
- redirect = CONSOLE_OUTPUT + '&title=%s(1)' % server.name
- self.assertRedirectsNoFollow(res, redirect)
-
- @test.create_stubs({api.nova: ('server_spice_console',)})
- def test_instance_spice_exception(self):
- server = self.servers.first()
-
- api.nova.server_spice_console(IsA(http.HttpRequest), server.id) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:spice',
- args=[server.id])
- res = self.client.get(url)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_get',
- 'snapshot_create',
- 'server_list',
- 'flavor_list',
- 'server_delete'),
- cinder: ('volume_snapshot_list',),
- api.glance: ('image_list_detailed',)})
- def test_create_instance_snapshot(self):
- server = self.servers.first()
-
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
- api.nova.snapshot_create(IsA(http.HttpRequest),
- server.id,
- "snapshot1").AndReturn(self.snapshots.first())
-
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- marker=None).AndReturn([[], False])
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([])
-
- self.mox.ReplayAll()
-
- formData = {'instance_id': server.id,
- 'method': 'CreateSnapshot',
- 'name': 'snapshot1'}
- url = reverse('horizon:project:images_and_snapshots:snapshots:create',
- args=[server.id])
- redir_url = reverse('horizon:project:images_and_snapshots:index')
- res = self.client.post(url, formData)
- self.assertRedirects(res, redir_url)
-
- instance_update_get_stubs = {
- api.nova: ('server_get',),
- api.network: ('security_group_list',
- 'server_security_groups',)}
-
- @test.create_stubs(instance_update_get_stubs)
- def test_instance_update_get(self):
- server = self.servers.first()
-
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn([])
- api.network.server_security_groups(IsA(http.HttpRequest),
- server.id).AndReturn([])
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:update', args=[server.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- @test.create_stubs(instance_update_get_stubs)
- def test_instance_update_get_server_get_exception(self):
- server = self.servers.first()
-
- api.nova.server_get(IsA(http.HttpRequest), server.id) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:update',
- args=[server.id])
- res = self.client.get(url)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def _instance_update_post(self, server_id, server_name, secgroups):
- formData = {'name': server_name,
- 'default_role': 'member',
- 'role_member': secgroups}
- url = reverse('horizon:project:instances:update',
- args=[server_id])
- return self.client.post(url, formData)
-
- instance_update_post_stubs = {
- api.nova: ('server_get', 'server_update'),
- api.network: ('security_group_list',
- 'server_security_groups',
- 'server_update_security_groups')}
-
- @test.create_stubs(instance_update_post_stubs)
- def test_instance_update_post(self):
- server = self.servers.first()
- secgroups = self.security_groups.list()[:3]
-
- server_groups = [secgroups[0], secgroups[1]]
- wanted_groups = [secgroups[1].id, secgroups[2].id]
-
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(secgroups)
- api.network.server_security_groups(IsA(http.HttpRequest),
- server.id).AndReturn(server_groups)
-
- api.nova.server_update(IsA(http.HttpRequest),
- server.id,
- server.name).AndReturn(server)
- api.network.server_update_security_groups(IsA(http.HttpRequest),
- server.id,
- wanted_groups)
-
- self.mox.ReplayAll()
-
- res = self._instance_update_post(server.id, server.name, wanted_groups)
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs(instance_update_post_stubs)
- def test_instance_update_post_api_exception(self):
- server = self.servers.first()
-
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn([])
- api.network.server_security_groups(IsA(http.HttpRequest),
- server.id).AndReturn([])
-
- api.nova.server_update(IsA(http.HttpRequest), server.id, server.name) \
- .AndRaise(self.exceptions.nova)
- api.network.server_update_security_groups(
- IsA(http.HttpRequest), server.id, [])
-
- self.mox.ReplayAll()
-
- res = self._instance_update_post(server.id, server.name, [])
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs(instance_update_post_stubs)
- def test_instance_update_post_secgroup_api_exception(self):
- server = self.servers.first()
-
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn([])
- api.network.server_security_groups(IsA(http.HttpRequest),
- server.id).AndReturn([])
-
- api.nova.server_update(IsA(http.HttpRequest),
- server.id,
- server.name).AndReturn(server)
- api.network.server_update_security_groups(
- IsA(http.HttpRequest),
- server.id, []).AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- res = self._instance_update_post(server.id, server.name, [])
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('flavor_list',
- 'keypair_list',
- 'tenant_absolute_limits',
- 'availability_zone_list',),
- api.network: ('security_group_list',),
- cinder: ('volume_snapshot_list',
- 'volume_list',),
- api.neutron: ('network_list',),
- api.glance: ('image_list_detailed',)})
- def test_launch_instance_get(self):
- image = self.images.first()
-
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False) \
- .AndReturn(self.networks.list()[:1])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True) \
- .AndReturn(self.networks.list()[1:])
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\
- .AndReturn(self.limits['absolute'])
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.keypair_list(IsA(http.HttpRequest)) \
- .AndReturn(self.keypairs.list())
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(self.security_groups.list())
- api.nova.availability_zone_list(IsA(http.HttpRequest)) \
- .AndReturn(self.availability_zones.list())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:launch')
- params = urlencode({"source_type": "image_id",
- "source_id": image.id})
- res = self.client.get("%s?%s" % (url, params))
-
- workflow = res.context['workflow']
- self.assertTemplateUsed(res, WorkflowView.template_name)
- self.assertEqual(res.context['workflow'].name, LaunchInstance.name)
- step = workflow.get_step("setinstancedetailsaction")
- self.assertEqual(step.action.initial['image_id'], image.id)
- self.assertQuerysetEqual(workflow.steps,
- ['<SetInstanceDetails: setinstancedetailsaction>',
- '<SetAccessControls: setaccesscontrolsaction>',
- '<SetNetwork: setnetworkaction>',
- '<VolumeOptions: volumeoptionsaction>',
- '<PostCreationStep: customizeaction>'])
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.neutron: ('network_list',),
- api.nova: ('flavor_list',
- 'keypair_list',
- 'availability_zone_list',
- 'server_create',),
- api.network: ('security_group_list',),
- cinder: ('volume_list',
- 'volume_snapshot_list',)})
- def test_launch_instance_post(self):
- flavor = self.flavors.first()
- image = self.images.first()
- keypair = self.keypairs.first()
- server = self.servers.first()
- sec_group = self.security_groups.first()
- avail_zone = self.availability_zones.first()
- customization_script = 'user data'
- nics = [{"net-id": self.networks.first().id, "v4-fixed-ip": ''}]
-
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.keypair_list(IsA(http.HttpRequest)) \
- .AndReturn(self.keypairs.list())
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(self.security_groups.list())
- api.nova.availability_zone_list(IsA(http.HttpRequest)) \
- .AndReturn(self.availability_zones.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False) \
- .AndReturn(self.networks.list()[:1])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True) \
- .AndReturn(self.networks.list()[1:])
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn([])
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([])
- api.nova.server_create(IsA(http.HttpRequest),
- server.name,
- image.id,
- flavor.id,
- keypair.name,
- customization_script,
- [sec_group.name],
- None,
- nics=nics,
- availability_zone=avail_zone.zoneName,
- instance_count=IsA(int),
- admin_pass=u'')
-
- self.mox.ReplayAll()
-
- form_data = {'flavor': flavor.id,
- 'source_type': 'image_id',
- 'image_id': image.id,
- 'keypair': keypair.name,
- 'name': server.name,
- 'customization_script': customization_script,
- 'project_id': self.tenants.first().id,
- 'user_id': self.user.id,
- 'groups': sec_group.name,
- 'availability_zone': avail_zone.zoneName,
- 'volume_type': '',
- 'network': self.networks.first().id,
- 'count': 1}
- url = reverse('horizon:project:instances:launch')
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.neutron: ('network_list',),
- api.nova: ('flavor_list',
- 'tenant_absolute_limits',
- 'keypair_list',
- 'availability_zone_list',
- 'server_create',),
- api.network: ('security_group_list',),
- cinder: ('volume_list',
- 'volume_snapshot_list',)})
- def test_launch_instance_post_boot_from_volume_with_image(self):
- flavor = self.flavors.first()
- image = self.images.first()
- keypair = self.keypairs.first()
- server = self.servers.first()
- volume = self.volumes.first()
- sec_group = self.security_groups.first()
- customization_script = 'user data'
- device_name = u'vda'
- volume_choice = "%s:vol" % volume.id
-
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest)) \
- .AndReturn(self.limits['absolute'])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([[], False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False) \
- .AndReturn(self.networks.list()[:1])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True) \
- .AndReturn(self.networks.list()[1:])
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.keypair_list(IsA(http.HttpRequest)) \
- .AndReturn(self.keypairs.list())
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(self.security_groups.list())
- api.nova.availability_zone_list(IsA(http.HttpRequest)) \
- .AndReturn(self.availability_zones.list())
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([])
-
- self.mox.ReplayAll()
-
- form_data = {'flavor': flavor.id,
- 'source_type': 'image_id',
- 'image_id': image.id,
- 'keypair': keypair.name,
- 'name': server.name,
- 'customization_script': customization_script,
- 'project_id': self.tenants.first().id,
- 'user_id': self.user.id,
- 'groups': sec_group.name,
- 'volume_type': 'volume_id',
- 'volume_id': volume_choice,
- 'device_name': device_name,
- 'network': self.networks.first().id,
- 'count': 1,
- 'admin_pass': 'password',
- 'confirm_admin_pass': 'password'}
- url = reverse('horizon:project:instances:launch')
- res = self.client.post(url, form_data)
-
- self.assertFormErrors(res, 1, "select an instance "
- "source when booting from a "
- "Volume. The Volume is your "
- "source and should contain "
- "the operating system.")
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.neutron: ('network_list',),
- api.nova: ('flavor_list',
- 'keypair_list',
- 'availability_zone_list',
- 'server_create',),
- api.network: ('security_group_list',),
- cinder: ('volume_list',
- 'volume_snapshot_list',)})
- def test_launch_instance_post_boot_from_volume(self):
- flavor = self.flavors.first()
- keypair = self.keypairs.first()
- server = self.servers.first()
- volume = self.volumes.first()
- sec_group = self.security_groups.first()
- avail_zone = self.availability_zones.first()
- customization_script = 'user data'
- device_name = u'vda'
- volume_choice = "%s:vol" % volume.id
- block_device_mapping = {device_name: u"%s::0" % volume_choice}
- nics = [{"net-id": self.networks.first().id, "v4-fixed-ip": ''}]
-
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.keypair_list(IsA(http.HttpRequest)) \
- .AndReturn(self.keypairs.list())
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(self.security_groups.list())
- api.nova.availability_zone_list(IsA(http.HttpRequest)) \
- .AndReturn(self.availability_zones.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False) \
- .AndReturn(self.networks.list()[:1])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True) \
- .AndReturn(self.networks.list()[1:])
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([])
- api.nova.server_create(IsA(http.HttpRequest),
- server.name,
- '',
- flavor.id,
- keypair.name,
- customization_script,
- [sec_group.name],
- block_device_mapping,
- nics=nics,
- availability_zone=avail_zone.zoneName,
- instance_count=IsA(int),
- admin_pass=u'')
-
- self.mox.ReplayAll()
-
- form_data = {'flavor': flavor.id,
- 'source_type': 'image_id',
- 'keypair': keypair.name,
- 'name': server.name,
- 'customization_script': customization_script,
- 'project_id': self.tenants.first().id,
- 'user_id': self.user.id,
- 'groups': sec_group.name,
- 'availability_zone': avail_zone.zoneName,
- 'volume_type': 'volume_id',
- 'volume_id': volume_choice,
- 'device_name': device_name,
- 'network': self.networks.first().id,
- 'count': 1}
- url = reverse('horizon:project:instances:launch')
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.neutron: ('network_list',),
- api.nova: ('server_create',
- 'flavor_list',
- 'keypair_list',
- 'availability_zone_list',),
- api.network: ('security_group_list',),
- cinder: ('volume_list',
- 'volume_snapshot_list',)})
- def test_launch_instance_post_no_images_available_boot_from_volume(self):
- flavor = self.flavors.first()
- keypair = self.keypairs.first()
- server = self.servers.first()
- volume = self.volumes.first()
- sec_group = self.security_groups.first()
- avail_zone = self.availability_zones.first()
- customization_script = 'user data'
- device_name = u'vda'
- volume_choice = "%s:vol" % volume.id
- block_device_mapping = {device_name: u"%s::0" % volume_choice}
- nics = [{"net-id": self.networks.first().id, "v4-fixed-ip": ''}]
-
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.keypair_list(IsA(http.HttpRequest)) \
- .AndReturn(self.keypairs.list())
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(self.security_groups.list())
- api.nova.availability_zone_list(IsA(http.HttpRequest)) \
- .AndReturn(self.availability_zones.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False) \
- .AndReturn(self.networks.list()[:1])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True) \
- .AndReturn(self.networks.list()[1:])
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([])
-
- api.nova.server_create(IsA(http.HttpRequest),
- server.name,
- '',
- flavor.id,
- keypair.name,
- customization_script,
- [sec_group.name],
- block_device_mapping,
- nics=nics,
- availability_zone=avail_zone.zoneName,
- instance_count=IsA(int),
- admin_pass=u'')
-
- self.mox.ReplayAll()
-
- form_data = {'flavor': flavor.id,
- 'source_type': 'image_id',
- 'image_id': '',
- 'keypair': keypair.name,
- 'name': server.name,
- 'customization_script': customization_script,
- 'project_id': self.tenants.first().id,
- 'user_id': self.user.id,
- 'groups': sec_group.name,
- 'availability_zone': avail_zone.zoneName,
- 'network': self.networks.first().id,
- 'volume_type': 'volume_id',
- 'volume_id': volume_choice,
- 'device_name': device_name,
- 'count': 1}
- url = reverse('horizon:project:instances:launch')
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.neutron: ('network_list',),
- api.nova: ('flavor_list',
- 'keypair_list',
- 'availability_zone_list',
- 'tenant_absolute_limits',),
- api.network: ('security_group_list',),
- cinder: ('volume_list',
- 'volume_snapshot_list',)})
- def test_launch_instance_post_no_images_available(self):
- flavor = self.flavors.first()
- keypair = self.keypairs.first()
- server = self.servers.first()
- sec_group = self.security_groups.first()
- avail_zone = self.availability_zones.first()
- customization_script = 'user data'
-
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest)) \
- .AndReturn(self.limits['absolute'])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([[], False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False) \
- .AndReturn(self.networks.list()[:1])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True) \
- .AndReturn(self.networks.list()[1:])
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.keypair_list(IsA(http.HttpRequest)) \
- .AndReturn(self.keypairs.list())
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(self.security_groups.list())
- api.nova.availability_zone_list(IsA(http.HttpRequest)) \
- .AndReturn(self.availability_zones.list())
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn([])
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([])
-
- self.mox.ReplayAll()
-
- form_data = {'flavor': flavor.id,
- 'source_type': 'image_id',
- 'image_id': '',
- 'keypair': keypair.name,
- 'name': server.name,
- 'customization_script': customization_script,
- 'project_id': self.tenants.first().id,
- 'user_id': self.user.id,
- 'groups': sec_group.name,
- 'availability_zone': avail_zone.zoneName,
- 'volume_type': '',
- 'count': 1}
- url = reverse('horizon:project:instances:launch')
- res = self.client.post(url, form_data)
-
- self.assertFormErrors(res, 1, "There are no image sources "
- "available; you must first "
- "create an image before "
- "attemtping to launch an "
- "instance.")
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.neutron: ('network_list',),
- cinder: ('volume_list',
- 'volume_snapshot_list',),
- api.network: ('security_group_list',),
- api.nova: ('flavor_list',
- 'keypair_list',
- 'tenant_absolute_limits',
- 'availability_zone_list',)})
- def test_launch_flavorlist_error(self):
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False) \
- .AndReturn(self.networks.list()[:1])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True) \
- .AndReturn(self.networks.list()[1:])
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest)) \
- .AndReturn(self.limits['absolute'])
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndRaise(self.exceptions.nova)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndRaise(self.exceptions.nova)
- api.nova.keypair_list(IsA(http.HttpRequest)) \
- .AndReturn(self.keypairs.list())
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(self.security_groups.list())
- api.nova.availability_zone_list(IsA(http.HttpRequest)) \
- .AndReturn(self.availability_zones.list())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:launch')
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.neutron: ('network_list',),
- api.nova: ('flavor_list',
- 'keypair_list',
- 'availability_zone_list',
- 'server_create',),
- api.network: ('security_group_list',),
- cinder: ('volume_list',
- 'volume_snapshot_list',)})
- def test_launch_form_keystone_exception(self):
- flavor = self.flavors.first()
- image = self.images.first()
- keypair = self.keypairs.first()
- server = self.servers.first()
- sec_group = self.security_groups.first()
- avail_zone = self.availability_zones.first()
- customization_script = 'userData'
- nics = [{"net-id": self.networks.first().id, "v4-fixed-ip": ''}]
-
- cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
- api.nova.keypair_list(IgnoreArg()).AndReturn(self.keypairs.list())
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(self.security_groups.list())
- api.nova.availability_zone_list(IsA(http.HttpRequest)) \
- .AndReturn(self.availability_zones.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False) \
- .AndReturn(self.networks.list()[:1])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True) \
- .AndReturn(self.networks.list()[1:])
- cinder.volume_list(IgnoreArg()).AndReturn(self.volumes.list())
- api.nova.server_create(IsA(http.HttpRequest),
- server.name,
- image.id,
- flavor.id,
- keypair.name,
- customization_script,
- [sec_group.name],
- None,
- nics=nics,
- availability_zone=avail_zone.zoneName,
- instance_count=IsA(int),
- admin_pass='password') \
- .AndRaise(self.exceptions.keystone)
-
- self.mox.ReplayAll()
-
- form_data = {'flavor': flavor.id,
- 'source_type': 'image_id',
- 'image_id': image.id,
- 'availability_zone': avail_zone.zoneName,
- 'keypair': keypair.name,
- 'name': server.name,
- 'customization_script': customization_script,
- 'project_id': self.tenants.first().id,
- 'user_id': self.user.id,
- 'groups': sec_group.name,
- 'volume_type': '',
- 'network': self.networks.first().id,
- 'count': 1,
- 'admin_pass': 'password',
- 'confirm_admin_pass': 'password'}
- url = reverse('horizon:project:instances:launch')
- res = self.client.post(url, form_data)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.glance: ('image_list_detailed',),
- api.neutron: ('network_list',),
- api.nova: ('flavor_list',
- 'keypair_list',
- 'tenant_absolute_limits',
- 'availability_zone_list',),
- api.network: ('security_group_list',),
- cinder: ('volume_list',
- 'volume_snapshot_list',)})
- def test_launch_form_instance_count_error(self):
- flavor = self.flavors.first()
- image = self.images.first()
- keypair = self.keypairs.first()
- server = self.servers.first()
- volume = self.volumes.first()
- sec_group = self.security_groups.first()
- avail_zone = self.availability_zones.first()
- customization_script = 'user data'
- device_name = u'vda'
- volume_choice = "%s:vol" % volume.id
-
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.keypair_list(IsA(http.HttpRequest)) \
- .AndReturn(self.keypairs.list())
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(self.security_groups.list())
- api.nova.availability_zone_list(IsA(http.HttpRequest)) \
- .AndReturn(self.availability_zones.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False) \
- .AndReturn(self.networks.list()[:1])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True) \
- .AndReturn(self.networks.list()[1:])
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([])
-
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest)) \
- .AndReturn(self.limits['absolute'])
-
- self.mox.ReplayAll()
-
- form_data = {'flavor': flavor.id,
- 'source_type': 'image_id',
- 'image_id': image.id,
- 'availability_zone': avail_zone.zoneName,
- 'keypair': keypair.name,
- 'name': server.name,
- 'customization_script': customization_script,
- 'project_id': self.tenants.first().id,
- 'user_id': self.user.id,
- 'groups': sec_group.name,
- 'volume_type': 'volume_id',
- 'volume_id': volume_choice,
- 'device_name': device_name,
- 'count': 0}
- url = reverse('horizon:project:instances:launch')
- res = self.client.post(url, form_data)
-
- self.assertContains(res, "greater than or equal to 1")
-
- @test.create_stubs({api.nova: ('flavor_list', 'server_list',
- 'tenant_absolute_limits',
- 'extension_supported',)})
- def test_launch_button_disabled_when_quota_exceeded(self):
- limits = self.limits['absolute']
- limits['totalInstancesUsed'] = limits['maxTotalInstances']
-
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
- .MultipleTimes().AndReturn(limits)
-
- self.mox.ReplayAll()
-
- launch = LaunchLink()
- url = launch.get_link_url()
- classes = list(launch.get_default_classes()) + list(launch.classes)
- link_name = "%s (%s)" % (unicode(launch.verbose_name),
- "Quota exceeded")
- expected_string = "<a href='%s' id='instances__action_launch' " \
- "title='%s' class='%s disabled'>%s</a>" \
- % (url, link_name, " ".join(classes), link_name)
-
- res = self.client.get(INDEX_URL)
- self.assertContains(res, expected_string, html=True,
- msg_prefix="The launch button is not disabled")
-
- @test.create_stubs({api.nova: ('flavor_list', 'server_list',
- 'tenant_absolute_limits',
- 'extension_supported',)})
- def test_index_options_after_migrate(self):
- server = self.servers.first()
- server.status = "VERIFY_RESIZE"
- api.nova.extension_supported('AdminActions',
- IsA(http.HttpRequest)) \
- .MultipleTimes().AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
- .MultipleTimes().AndReturn(self.limits['absolute'])
-
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
- self.assertContains(res, "instances__confirm")
- self.assertContains(res, "instances__revert")
-
- @test.create_stubs({api.nova: ('flavor_list',
- 'keypair_list',
- 'availability_zone_list',
- 'tenant_absolute_limits',),
- api.network: ('security_group_list',),
- cinder: ('volume_snapshot_list',
- 'volume_list',),
- api.neutron: ('network_list',),
- api.glance: ('image_list_detailed',)})
- def test_select_default_keypair_if_only_one(self):
- keypair = self.keypairs.first()
-
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False) \
- .AndReturn(self.networks.list()[:1])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True) \
- .AndReturn(self.networks.list()[1:])
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest)) \
- .AndReturn(self.limits['absolute'])
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.keypair_list(IsA(http.HttpRequest)) \
- .AndReturn([keypair])
- api.network.security_group_list(IsA(http.HttpRequest)) \
- .AndReturn(self.security_groups.list())
- api.nova.availability_zone_list(IsA(http.HttpRequest)) \
- .AndReturn(self.availability_zones.list())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:launch')
- res = self.client.get(url)
- self.assertContains(res, "<option selected='selected' value='%(key)s'>"
- "%(key)s</option>" % {'key': keypair.name},
- html=True,
- msg_prefix="The default keypair was not selected.")
-
- @test.create_stubs({api.network: ('floating_ip_target_get_by_instance',
- 'tenant_floating_ip_allocate',
- 'floating_ip_associate'),
- api.nova: ('server_list',
- 'flavor_list')})
- def test_associate_floating_ip(self):
- server = self.servers.first()
- fip = self.q_floating_ips.first()
-
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
- api.network.floating_ip_target_get_by_instance(
- IsA(http.HttpRequest),
- server.id).AndReturn(server.id)
- api.network.tenant_floating_ip_allocate(
- IsA(http.HttpRequest)).AndReturn(fip)
- api.network.floating_ip_associate(
- IsA(http.HttpRequest), fip.id, server.id)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__associate-simple__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.network: ('floating_ip_target_get_by_instance',
- 'tenant_floating_ip_list',
- 'floating_ip_disassociate',
- 'tenant_floating_ip_release'),
- api.nova: ('server_list',
- 'flavor_list')})
- def test_disassociate_floating_ip(self):
- server = self.servers.first()
- fip = self.q_floating_ips.first()
- fip.port_id = server.id
-
- search_opts = {'marker': None, 'paginate': True}
- api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
- .AndReturn([self.servers.list(), False])
- api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
- api.network.floating_ip_target_get_by_instance(
- IsA(http.HttpRequest),
- server.id).AndReturn(server.id)
- api.network.tenant_floating_ip_list(
- IsA(http.HttpRequest)).AndReturn([fip])
- api.network.floating_ip_disassociate(
- IsA(http.HttpRequest), fip.id, server.id)
- api.network.tenant_floating_ip_release(
- IsA(http.HttpRequest), fip.id)
-
- self.mox.ReplayAll()
-
- formData = {'action': 'instances__disassociate__%s' % server.id}
- res = self.client.post(INDEX_URL, formData)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_get',
- 'flavor_list',
- 'tenant_absolute_limits')})
- def test_instance_resize_get(self):
- server = self.servers.first()
- api.nova.server_get(IsA(http.HttpRequest), server.id) \
- .AndReturn(server)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest)) \
- .AndReturn(self.limits['absolute'])
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:resize', args=[server.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- @test.create_stubs({api.nova: ('server_get',
- 'flavor_list',)})
- def test_instance_resize_get_server_get_exception(self):
- server = self.servers.first()
-
- api.nova.server_get(IsA(http.HttpRequest), server.id) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:resize',
- args=[server.id])
- res = self.client.get(url)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.nova: ('server_get',
- 'flavor_list',)})
- def test_instance_resize_get_flavor_list_exception(self):
- server = self.servers.first()
-
- api.nova.server_get(IsA(http.HttpRequest), server.id) \
- .AndReturn(server)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:instances:resize',
- args=[server.id])
- res = self.client.get(url)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def _instance_resize_post(self, server_id, flavor_id):
- formData = {'flavor': flavor_id,
- 'default_role': 'member'}
- url = reverse('horizon:project:instances:resize',
- args=[server_id])
- return self.client.post(url, formData)
-
- instance_resize_post_stubs = {
- api.nova: ('server_get', 'server_resize',
- 'flavor_list', 'flavor_get')}
-
- @test.create_stubs(instance_resize_post_stubs)
- def test_instance_resize_post(self):
- server = self.servers.first()
- flavor = self.flavors.first()
-
- api.nova.server_get(IsA(http.HttpRequest), server.id) \
- .AndReturn(server)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.server_resize(IsA(http.HttpRequest), server.id, flavor.id) \
- .AndReturn([])
-
- self.mox.ReplayAll()
-
- res = self._instance_resize_post(server.id, flavor.id)
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs(instance_resize_post_stubs)
- def test_instance_resize_post_api_exception(self):
- server = self.servers.first()
- flavor = self.flavors.first()
-
- api.nova.server_get(IsA(http.HttpRequest), server.id) \
- .AndReturn(server)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.server_resize(IsA(http.HttpRequest), server.id, flavor.id) \
- .AndRaise(self.exceptions.nova)
-
- self.mox.ReplayAll()
-
- res = self._instance_resize_post(server.id, flavor.id)
- self.assertRedirectsNoFollow(res, INDEX_URL)
diff --git a/openstack_dashboard/dashboards/project/instances/urls.py b/openstack_dashboard/dashboards/project/instances/urls.py
deleted file mode 100644
index e80981dd..00000000
--- a/openstack_dashboard/dashboards/project/instances/urls.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.instances.views import DetailView
-from openstack_dashboard.dashboards.project.instances.views import IndexView
-from openstack_dashboard.dashboards.project.instances.views import \
- LaunchInstanceView
-from openstack_dashboard.dashboards.project.instances.views import ResizeView
-from openstack_dashboard.dashboards.project.instances.views import UpdateView
-
-
-INSTANCES = r'^(?P<instance_id>[^/]+)/%s$'
-VIEW_MOD = 'openstack_dashboard.dashboards.project.instances.views'
-
-
-urlpatterns = patterns(VIEW_MOD,
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^launch$', LaunchInstanceView.as_view(), name='launch'),
- url(r'^(?P<instance_id>[^/]+)/$', DetailView.as_view(), name='detail'),
- url(INSTANCES % 'update', UpdateView.as_view(), name='update'),
- url(INSTANCES % 'console', 'console', name='console'),
- url(INSTANCES % 'vnc', 'vnc', name='vnc'),
- url(INSTANCES % 'spice', 'spice', name='spice'),
- url(INSTANCES % 'resize', ResizeView.as_view(), name='resize'),
-)
diff --git a/openstack_dashboard/dashboards/project/instances/views.py b/openstack_dashboard/dashboards/project/instances/views.py
deleted file mode 100644
index 0d39e563..00000000
--- a/openstack_dashboard/dashboards/project/instances/views.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing instances.
-"""
-import logging
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django import http
-from django import shortcuts
-from django.utils.datastructures import SortedDict
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-from horizon import tabs
-from horizon import workflows
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.instances.tables import \
- InstancesTable
-from openstack_dashboard.dashboards.project.instances.tabs import \
- InstanceDetailTabs
-from openstack_dashboard.dashboards.project.instances.workflows import \
- LaunchInstance
-from openstack_dashboard.dashboards.project.instances.workflows import \
- ResizeInstance
-from openstack_dashboard.dashboards.project.instances.workflows import \
- UpdateInstance
-
-
-LOG = logging.getLogger(__name__)
-
-
-class IndexView(tables.DataTableView):
- table_class = InstancesTable
- template_name = 'project/instances/index.html'
-
- def has_more_data(self, table):
- return self._more
-
- def get_data(self):
- marker = self.request.GET.get(
- InstancesTable._meta.pagination_param, None)
- # Gather our instances
- try:
- instances, self._more = api.nova.server_list(
- self.request,
- search_opts={'marker': marker,
- 'paginate': True})
- except:
- self._more = False
- instances = []
- exceptions.handle(self.request,
- _('Unable to retrieve instances.'))
- # Gather our flavors and correlate our instances to them
- if instances:
- try:
- flavors = api.nova.flavor_list(self.request)
- except:
- flavors = []
- exceptions.handle(self.request, ignore=True)
-
- full_flavors = SortedDict([(str(flavor.id), flavor)
- for flavor in flavors])
- # Loop through instances to get flavor info.
- for instance in instances:
- try:
- flavor_id = instance.flavor["id"]
- if flavor_id in full_flavors:
- instance.full_flavor = full_flavors[flavor_id]
- else:
- # If the flavor_id is not in full_flavors list,
- # get it via nova api.
- instance.full_flavor = api.nova.flavor_get(
- self.request, flavor_id)
- except:
- msg = _('Unable to retrieve instance size information.')
- exceptions.handle(self.request, msg)
- return instances
-
-
-class LaunchInstanceView(workflows.WorkflowView):
- workflow_class = LaunchInstance
-
- def get_initial(self):
- initial = super(LaunchInstanceView, self).get_initial()
- initial['project_id'] = self.request.user.tenant_id
- initial['user_id'] = self.request.user.id
- return initial
-
-
-def console(request, instance_id):
- try:
- # TODO(jakedahn): clean this up once the api supports tailing.
- tail = request.GET.get('length', None)
- data = api.nova.server_console_output(request,
- instance_id,
- tail_length=tail)
- except:
- data = _('Unable to get log for instance "%s".') % instance_id
- exceptions.handle(request, ignore=True)
- response = http.HttpResponse(mimetype='text/plain')
- response.write(data)
- response.flush()
- return response
-
-
-def vnc(request, instance_id):
- try:
- console = api.nova.server_vnc_console(request, instance_id)
- instance = api.nova.server_get(request, instance_id)
- return shortcuts.redirect(console.url +
- ("&title=%s(%s)" % (instance.name, instance_id)))
- except:
- redirect = reverse("horizon:project:instances:index")
- msg = _('Unable to get VNC console for instance "%s".') % instance_id
- exceptions.handle(request, msg, redirect=redirect)
-
-
-def spice(request, instance_id):
- try:
- console = api.nova.server_spice_console(request, instance_id)
- instance = api.nova.server_get(request, instance_id)
- return shortcuts.redirect(console.url +
- ("&title=%s(%s)" % (instance.name, instance_id)))
- except:
- redirect = reverse("horizon:project:instances:index")
- msg = _('Unable to get SPICE console for instance "%s".') % instance_id
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class UpdateView(workflows.WorkflowView):
- workflow_class = UpdateInstance
- success_url = reverse_lazy("horizon:project:instances:index")
-
- def get_context_data(self, **kwargs):
- context = super(UpdateView, self).get_context_data(**kwargs)
- context["instance_id"] = self.kwargs['instance_id']
- return context
-
- def get_object(self, *args, **kwargs):
- if not hasattr(self, "_object"):
- instance_id = self.kwargs['instance_id']
- try:
- self._object = api.nova.server_get(self.request, instance_id)
- except:
- redirect = reverse("horizon:project:instances:index")
- msg = _('Unable to retrieve instance details.')
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_initial(self):
- initial = super(UpdateView, self).get_initial()
- initial.update({'instance_id': self.kwargs['instance_id'],
- 'name': getattr(self.get_object(), 'name', '')})
- return initial
-
-
-class DetailView(tabs.TabView):
- tab_group_class = InstanceDetailTabs
- template_name = 'project/instances/detail.html'
-
- def get_context_data(self, **kwargs):
- context = super(DetailView, self).get_context_data(**kwargs)
- context["instance"] = self.get_data()
- return context
-
- def get_data(self):
- if not hasattr(self, "_instance"):
- try:
- instance_id = self.kwargs['instance_id']
- instance = api.nova.server_get(self.request, instance_id)
- instance.volumes = api.nova.instance_volumes_list(self.request,
- instance_id)
- # Sort by device name
- instance.volumes.sort(key=lambda vol: vol.device)
- instance.full_flavor = api.nova.flavor_get(
- self.request, instance.flavor["id"])
- instance.security_groups = api.network.server_security_groups(
- self.request, instance_id)
- except:
- redirect = reverse('horizon:project:instances:index')
- exceptions.handle(self.request,
- _('Unable to retrieve details for '
- 'instance "%s".') % instance_id,
- redirect=redirect)
- self._instance = instance
- return self._instance
-
- def get_tabs(self, request, *args, **kwargs):
- instance = self.get_data()
- return self.tab_group_class(request, instance=instance, **kwargs)
-
-
-class ResizeView(workflows.WorkflowView):
- workflow_class = ResizeInstance
- success_url = reverse_lazy("horizon:project:instances:index")
-
- def get_context_data(self, **kwargs):
- context = super(ResizeView, self).get_context_data(**kwargs)
- context["instance_id"] = self.kwargs['instance_id']
- return context
-
- def get_object(self, *args, **kwargs):
- if not hasattr(self, "_object"):
- instance_id = self.kwargs['instance_id']
- try:
- self._object = api.nova.server_get(self.request, instance_id)
- flavor_id = self._object.flavor['id']
- flavors = self.get_flavors()
- if flavor_id in flavors:
- self._object.flavor_name = flavors[flavor_id].name
- else:
- flavor = api.nova.flavor_get(self.request, flavor_id)
- self._object.flavor_name = flavor.name
- except:
- redirect = reverse("horizon:project:instances:index")
- msg = _('Unable to retrieve instance details.')
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_flavors(self, *args, **kwargs):
- if not hasattr(self, "_flavors"):
- try:
- flavors = api.nova.flavor_list(self.request)
- self._flavors = SortedDict([(str(flavor.id), flavor)
- for flavor in flavors])
- except:
- redirect = reverse("horizon:project:instances:index")
- exceptions.handle(self.request,
- _('Unable to retrieve flavors.'), redirect=redirect)
- return self._flavors
-
- def get_initial(self):
- initial = super(ResizeView, self).get_initial()
- _object = self.get_object()
- if _object:
- initial.update({'instance_id': self.kwargs['instance_id'],
- 'old_flavor_id': _object.flavor['id'],
- 'old_flavor_name': getattr(_object, 'flavor_name', ''),
- 'flavors': self.get_flavors()})
- return initial
diff --git a/openstack_dashboard/dashboards/project/instances/workflows/__init__.py b/openstack_dashboard/dashboards/project/instances/workflows/__init__.py
deleted file mode 100644
index 2c19082f..00000000
--- a/openstack_dashboard/dashboards/project/instances/workflows/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from create_instance import LaunchInstance
-from resize_instance import ResizeInstance
-from update_instance import UpdateInstance
-
-assert LaunchInstance
-assert UpdateInstance
-assert ResizeInstance
diff --git a/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py b/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py
deleted file mode 100644
index 2da18729..00000000
--- a/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py
+++ /dev/null
@@ -1,546 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import json
-import logging
-
-from django.utils.text import normalize_newlines
-from django.utils.translation import ugettext_lazy as _
-from django.views.decorators.debug import sensitive_variables
-
-from horizon import exceptions
-from horizon import forms
-from horizon.utils import validators
-from horizon import workflows
-
-from openstack_dashboard import api
-from openstack_dashboard.api import cinder
-
-from openstack_dashboard.dashboards.project.images_and_snapshots.utils \
- import get_available_images
-
-
-LOG = logging.getLogger(__name__)
-
-
-class SelectProjectUserAction(workflows.Action):
- project_id = forms.ChoiceField(label=_("Project"))
- user_id = forms.ChoiceField(label=_("User"))
-
- def __init__(self, request, *args, **kwargs):
- super(SelectProjectUserAction, self).__init__(request, *args, **kwargs)
- # Set our project choices
- projects = [(tenant.id, tenant.name)
- for tenant in request.user.authorized_tenants]
- self.fields['project_id'].choices = projects
-
- # Set our user options
- users = [(request.user.id, request.user.username)]
- self.fields['user_id'].choices = users
-
- class Meta:
- name = _("Project & User")
- # Unusable permission so this is always hidden. However, we
- # keep this step in the workflow for validation/verification purposes.
- permissions = ("!",)
-
-
-class SelectProjectUser(workflows.Step):
- action_class = SelectProjectUserAction
- contributes = ("project_id", "user_id")
-
-
-class VolumeOptionsAction(workflows.Action):
- VOLUME_CHOICES = (
- ('', _("Don't boot from a volume.")),
- ("volume_id", _("Boot from volume.")),
- ("volume_snapshot_id", _("Boot from volume snapshot "
- "(creates a new volume).")),
- )
- # Boot from volume options
- volume_type = forms.ChoiceField(label=_("Volume Options"),
- choices=VOLUME_CHOICES,
- required=False)
- volume_id = forms.ChoiceField(label=_("Volume"), required=False)
- volume_snapshot_id = forms.ChoiceField(label=_("Volume Snapshot"),
- required=False)
- device_name = forms.CharField(label=_("Device Name"),
- required=False,
- initial="vda",
- help_text=_("Volume mount point (e.g. 'vda' "
- "mounts at '/dev/vda')."))
- delete_on_terminate = forms.BooleanField(label=_("Delete on Terminate"),
- initial=False,
- required=False,
- help_text=_("Delete volume on "
- "instance terminate"))
-
- class Meta:
- name = _("Volume Options")
- permissions = ('openstack.services.volume',)
- help_text_template = ("project/instances/"
- "_launch_volumes_help.html")
-
- def clean(self):
- cleaned_data = super(VolumeOptionsAction, self).clean()
- volume_opt = cleaned_data.get('volume_type', None)
-
- if volume_opt and not cleaned_data[volume_opt]:
- raise forms.ValidationError(_('Please choose a volume, or select '
- '%s.') % self.VOLUME_CHOICES[0][1])
- return cleaned_data
-
- def _get_volume_display_name(self, volume):
- if hasattr(volume, "volume_id"):
- vol_type = "snap"
- visible_label = _("Snapshot")
- else:
- vol_type = "vol"
- visible_label = _("Volume")
- return (("%s:%s" % (volume.id, vol_type)),
- (_("%(name)s - %(size)s GB (%(label)s)") %
- {'name': volume.display_name or volume.id,
- 'size': volume.size,
- 'label': visible_label}))
-
- def populate_volume_id_choices(self, request, context):
- volume_options = [("", _("Select Volume"))]
- try:
- volumes = [v for v in cinder.volume_list(self.request)
- if v.status == api.cinder.VOLUME_STATE_AVAILABLE]
- volume_options.extend([self._get_volume_display_name(vol)
- for vol in volumes])
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve list of volumes.'))
- return volume_options
-
- def populate_volume_snapshot_id_choices(self, request, context):
- volume_options = [("", _("Select Volume Snapshot"))]
- try:
- snapshots = cinder.volume_snapshot_list(self.request)
- snapshots = [s for s in snapshots
- if s.status == api.cinder.VOLUME_STATE_AVAILABLE]
- volume_options.extend([self._get_volume_display_name(snap)
- for snap in snapshots])
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve list of volume '
- 'snapshots.'))
-
- return volume_options
-
-
-class VolumeOptions(workflows.Step):
- action_class = VolumeOptionsAction
- depends_on = ("project_id", "user_id")
- contributes = ("volume_type",
- "volume_id",
- "device_name", # Can be None for an image.
- "delete_on_terminate")
-
- def contribute(self, data, context):
- context = super(VolumeOptions, self).contribute(data, context)
- # Translate form input to context for volume values.
- if "volume_type" in data and data["volume_type"]:
- context['volume_id'] = data.get(data['volume_type'], None)
-
- if not context.get("volume_type", ""):
- context['volume_type'] = self.action.VOLUME_CHOICES[0][0]
- context['volume_id'] = None
- context['device_name'] = None
- context['delete_on_terminate'] = None
- return context
-
-
-class SetInstanceDetailsAction(workflows.Action):
- SOURCE_TYPE_CHOICES = (
- ("image_id", _("Image")),
- ("instance_snapshot_id", _("Snapshot")),
- )
- source_type = forms.ChoiceField(label=_("Instance Source"),
- choices=SOURCE_TYPE_CHOICES)
- image_id = forms.ChoiceField(label=_("Image"), required=False)
- instance_snapshot_id = forms.ChoiceField(label=_("Instance Snapshot"),
- required=False)
- availability_zone = forms.ChoiceField(label=_("Availability Zone"),
- required=False)
- name = forms.CharField(max_length=80, label=_("Instance Name"))
- flavor = forms.ChoiceField(label=_("Flavor"),
- help_text=_("Size of image to launch."))
- count = forms.IntegerField(label=_("Instance Count"),
- min_value=1,
- initial=1,
- help_text=_("Number of instances to launch."))
-
- class Meta:
- name = _("Details")
- help_text_template = ("project/instances/"
- "_launch_details_help.html")
-
- def clean(self):
- cleaned_data = super(SetInstanceDetailsAction, self).clean()
-
- # Validate our instance source.
- source = cleaned_data['source_type']
- # There should always be at least one image_id choice, telling the user
- # that there are "No Images Available" so we check for 2 here...
- volume_type = self.data.get('volume_type', None)
- if volume_type: # Boot from volume
- if cleaned_data[source]:
- raise forms.ValidationError(_("You can't select an instance "
- "source when booting from a "
- "Volume. The Volume is your "
- "source and should contain "
- "the operating system."))
- else: # Boot from image / image_snapshot
- if source == 'image_id' and not \
- filter(lambda x: x[0] != '', self.fields['image_id'].choices):
- raise forms.ValidationError(_("There are no image sources "
- "available; you must first "
- "create an image before "
- "attemtping to launch an "
- "instance."))
- elif not cleaned_data[source]:
- raise forms.ValidationError(_("Please select an option for the"
- " instance source."))
-
- # Prevent launching multiple instances with the same volume.
- # TODO(gabriel): is it safe to launch multiple instances with
- # a snapshot since it should be cloned to new volumes?
- count = cleaned_data.get('count', 1)
- if volume_type and count > 1:
- msg = _('Launching multiple instances is only supported for '
- 'images and instance snapshots.')
- raise forms.ValidationError(msg)
-
- return cleaned_data
-
- def _init_images_cache(self):
- if not hasattr(self, '_images_cache'):
- self._images_cache = {}
-
- def populate_image_id_choices(self, request, context):
- self._init_images_cache()
- images = get_available_images(request, context.get('project_id'),
- self._images_cache)
- choices = [(image.id, image.name)
- for image in images
- if image.properties.get("image_type", '') != "snapshot"]
- if choices:
- choices.insert(0, ("", _("Select Image")))
- else:
- choices.insert(0, ("", _("No images available.")))
- return choices
-
- def populate_instance_snapshot_id_choices(self, request, context):
- self._init_images_cache()
- images = get_available_images(request, context.get('project_id'),
- self._images_cache)
- choices = [(image.id, image.name)
- for image in images
- if image.properties.get("image_type", '') == "snapshot"]
- if choices:
- choices.insert(0, ("", _("Select Instance Snapshot")))
- else:
- choices.insert(0, ("", _("No snapshots available.")))
- return choices
-
- def populate_flavor_choices(self, request, context):
- try:
- flavors = api.nova.flavor_list(request)
- flavor_list = [(flavor.id, "%s" % flavor.name)
- for flavor in flavors]
- except:
- flavor_list = []
- exceptions.handle(request,
- _('Unable to retrieve instance flavors.'))
- return sorted(flavor_list)
-
- def populate_availability_zone_choices(self, request, context):
- try:
- zones = api.nova.availability_zone_list(request)
- except:
- zones = []
- exceptions.handle(request,
- _('Unable to retrieve availability zones.'))
-
- zone_list = [(zone.zoneName, zone.zoneName)
- for zone in zones if zone.zoneState['available']]
- zone_list.sort()
- if zone_list:
- zone_list.insert(0, ("", _("Any Availability Zone")))
- else:
- zone_list.insert(0, ("", _("No availability zones found.")))
- return zone_list
-
- def get_help_text(self):
- extra = {}
- try:
- extra['usages'] = api.nova.tenant_absolute_limits(self.request)
- extra['usages_json'] = json.dumps(extra['usages'])
- flavors = json.dumps([f._info for f in
- api.nova.flavor_list(self.request)])
- extra['flavors'] = flavors
- except:
- exceptions.handle(self.request,
- _("Unable to retrieve quota information."))
- return super(SetInstanceDetailsAction, self).get_help_text(extra)
-
-
-class SetInstanceDetails(workflows.Step):
- action_class = SetInstanceDetailsAction
- contributes = ("source_type", "source_id", "availability_zone",
- "name", "count", "flavor")
-
- def prepare_action_context(self, request, context):
- if 'source_type' in context and 'source_id' in context:
- context[context['source_type']] = context['source_id']
- return context
-
- def contribute(self, data, context):
- context = super(SetInstanceDetails, self).contribute(data, context)
- # Allow setting the source dynamically.
- if ("source_type" in context and "source_id" in context
- and context["source_type"] not in context):
- context[context["source_type"]] = context["source_id"]
-
- # Translate form input to context for source values.
- if "source_type" in data:
- context["source_id"] = data.get(data['source_type'], None)
-
- return context
-
-
-KEYPAIR_IMPORT_URL = "horizon:project:access_and_security:keypairs:import"
-
-
-class SetAccessControlsAction(workflows.Action):
- keypair = forms.DynamicChoiceField(label=_("Keypair"),
- required=False,
- help_text=_("Which keypair to use for "
- "authentication."),
- add_item_link=KEYPAIR_IMPORT_URL)
- admin_pass = forms.RegexField(
- label=_("Admin Pass"),
- required=False,
- widget=forms.PasswordInput(render_value=False),
- regex=validators.password_validator(),
- error_messages={'invalid': validators.password_validator_msg()})
- confirm_admin_pass = forms.CharField(
- label=_("Confirm Admin Pass"),
- required=False,
- widget=forms.PasswordInput(render_value=False))
- groups = forms.MultipleChoiceField(label=_("Security Groups"),
- required=True,
- initial=["default"],
- widget=forms.CheckboxSelectMultiple(),
- help_text=_("Launch instance in these "
- "security groups."))
-
- class Meta:
- name = _("Access & Security")
- help_text = _("Control access to your instance via keypairs, "
- "security groups, and other mechanisms.")
-
- def populate_keypair_choices(self, request, context):
- try:
- keypairs = api.nova.keypair_list(request)
- keypair_list = [(kp.name, kp.name) for kp in keypairs]
- except:
- keypair_list = []
- exceptions.handle(request,
- _('Unable to retrieve keypairs.'))
- if keypair_list:
- if len(keypair_list) == 1:
- self.fields['keypair'].initial = keypair_list[0][0]
- keypair_list.insert(0, ("", _("Select a keypair")))
- else:
- keypair_list = (("", _("No keypairs available.")),)
- return keypair_list
-
- def populate_groups_choices(self, request, context):
- try:
- groups = api.network.security_group_list(request)
- security_group_list = [(sg.name, sg.name) for sg in groups]
- except:
- exceptions.handle(request,
- _('Unable to retrieve list of security groups'))
- security_group_list = []
- return security_group_list
-
- def clean(self):
- '''Check to make sure password fields match.'''
- cleaned_data = super(SetAccessControlsAction, self).clean()
- if 'admin_pass' in cleaned_data:
- if cleaned_data['admin_pass'] != cleaned_data.get(
- 'confirm_admin_pass', None):
- raise forms.ValidationError(_('Passwords do not match.'))
- return cleaned_data
-
-
-class SetAccessControls(workflows.Step):
- action_class = SetAccessControlsAction
- depends_on = ("project_id", "user_id")
- contributes = ("keypair_id", "security_group_ids",
- "admin_pass", "confirm_admin_pass")
-
- def contribute(self, data, context):
- if data:
- post = self.workflow.request.POST
- context['security_group_ids'] = post.getlist("groups")
- context['keypair_id'] = data.get("keypair", "")
- context['admin_pass'] = data.get("admin_pass", "")
- context['confirm_admin_pass'] = data.get("confirm_admin_pass", "")
- return context
-
-
-class CustomizeAction(workflows.Action):
- customization_script = forms.CharField(widget=forms.Textarea,
- label=_("Customization Script"),
- required=False,
- help_text=_("A script or set of "
- "commands to be "
- "executed after the "
- "instance has been "
- "built (max 16kb)."))
-
- class Meta:
- name = _("Post-Creation")
- help_text_template = ("project/instances/"
- "_launch_customize_help.html")
-
-
-class PostCreationStep(workflows.Step):
- action_class = CustomizeAction
- contributes = ("customization_script",)
-
-
-class SetNetworkAction(workflows.Action):
- network = forms.MultipleChoiceField(label=_("Networks"),
- required=True,
- widget=forms.CheckboxSelectMultiple(),
- error_messages={
- 'required': _(
- "At least one network must"
- " be specified.")},
- help_text=_("Launch instance with"
- " these networks"))
-
- class Meta:
- name = _("Networking")
- permissions = ('openstack.services.network',)
- help_text = _("Select networks for your instance.")
-
- def populate_network_choices(self, request, context):
- try:
- tenant_id = self.request.user.tenant_id
- networks = api.neutron.network_list_for_tenant(request, tenant_id)
- for n in networks:
- n.set_id_as_name_if_empty()
- network_list = [(network.id, network.name) for network in networks]
- except:
- network_list = []
- exceptions.handle(request,
- _('Unable to retrieve networks.'))
- return network_list
-
-
-class SetNetwork(workflows.Step):
- action_class = SetNetworkAction
- template_name = "project/instances/_update_networks.html"
- contributes = ("network_id",)
-
- def contribute(self, data, context):
- if data:
- networks = self.workflow.request.POST.getlist("network")
- # If no networks are explicitly specified, network list
- # contains an empty string, so remove it.
- networks = [n for n in networks if n != '']
- if networks:
- context['network_id'] = networks
- return context
-
-
-class LaunchInstance(workflows.Workflow):
- slug = "launch_instance"
- name = _("Launch Instance")
- finalize_button_name = _("Launch")
- success_message = _('Launched %(count)s named "%(name)s".')
- failure_message = _('Unable to launch %(count)s named "%(name)s".')
- success_url = "horizon:project:instances:index"
- default_steps = (SelectProjectUser,
- SetInstanceDetails,
- SetAccessControls,
- SetNetwork,
- VolumeOptions,
- PostCreationStep)
-
- def format_status_message(self, message):
- name = self.context.get('name', 'unknown instance')
- count = self.context.get('count', 1)
- if int(count) > 1:
- return message % {"count": _("%s instances") % count,
- "name": name}
- else:
- return message % {"count": _("instance"), "name": name}
-
- @sensitive_variables('context')
- def handle(self, request, context):
- custom_script = context.get('customization_script', '')
-
- # Determine volume mapping options
- if context.get('volume_type', None):
- if(context['delete_on_terminate']):
- del_on_terminate = 1
- else:
- del_on_terminate = 0
- mapping_opts = ("%s::%s"
- % (context['volume_id'], del_on_terminate))
- dev_mapping = {context['device_name']: mapping_opts}
- else:
- dev_mapping = None
-
- netids = context.get('network_id', None)
- if netids:
- nics = [{"net-id": netid, "v4-fixed-ip": ""}
- for netid in netids]
- else:
- nics = None
-
- avail_zone = context.get('availability_zone', None)
-
- try:
- api.nova.server_create(request,
- context['name'],
- context['source_id'],
- context['flavor'],
- context['keypair_id'],
- normalize_newlines(custom_script),
- context['security_group_ids'],
- dev_mapping,
- nics=nics,
- availability_zone=avail_zone,
- instance_count=int(context['count']),
- admin_pass=context['admin_pass'])
- return True
- except:
- exceptions.handle(request)
- return False
diff --git a/openstack_dashboard/dashboards/project/instances/workflows/resize_instance.py b/openstack_dashboard/dashboards/project/instances/workflows/resize_instance.py
deleted file mode 100644
index c0802d54..00000000
--- a/openstack_dashboard/dashboards/project/instances/workflows/resize_instance.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 CentRin Data, 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 json
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-from django.views.decorators.debug import sensitive_variables
-
-from horizon import exceptions
-from horizon import forms
-from horizon import workflows
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class SetFlavorChoiceAction(workflows.Action):
- old_flavor_id = forms.CharField(required=False, widget=forms.HiddenInput())
- old_flavor_name = forms.CharField(label=_("Old Flavor"),
- required=False,
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}
- ))
- flavor = forms.ChoiceField(label=_("New Flavor"),
- required=True,
- help_text=_("Choose the flavor to launch."))
-
- class Meta:
- name = _("Flavor Choice")
- slug = 'flavor_choice'
- help_text_template = ("project/instances/"
- "_flavors_and_quotas.html")
-
- def clean(self):
- cleaned_data = super(SetFlavorChoiceAction, self).clean()
- flavor = cleaned_data.get('flavor', None)
-
- if flavor is None or flavor == cleaned_data['old_flavor_id']:
- raise forms.ValidationError(_('Please choose a new flavor that '
- 'can not be same as the old one.'))
- return cleaned_data
-
- def populate_flavor_choices(self, request, context):
- flavors = context.get('flavors')
- flavor_list = [(flavor.id, '%s' % flavor.name)
- for flavor in flavors.values()]
- if flavor_list:
- flavor_list.insert(0, ("", _("Select an New Flavor")))
- else:
- flavor_list.insert(0, ("", _("No flavors available.")))
- return sorted(flavor_list)
-
- def get_help_text(self):
- extra = {}
- try:
- extra['usages'] = api.nova.tenant_absolute_limits(self.request)
- extra['usages_json'] = json.dumps(extra['usages'])
- flavors = json.dumps([f._info for f in
- api.nova.flavor_list(self.request)])
- extra['flavors'] = flavors
- except:
- exceptions.handle(self.request,
- _("Unable to retrieve quota information."))
- return super(SetFlavorChoiceAction, self).get_help_text(extra)
-
-
-class SetFlavorChoice(workflows.Step):
- action_class = SetFlavorChoiceAction
- depends_on = ("instance_id",)
- contributes = ("old_flavor_id", "old_flavor_name", "flavors", "flavor")
-
-
-class ResizeInstance(workflows.Workflow):
- slug = "resize_instance"
- name = _("Resize Instance")
- finalize_button_name = _("Resize")
- success_message = _('Resized instance "%s".')
- failure_message = _('Unable to resize instance "%s".')
- success_url = "horizon:project:instances:index"
- default_steps = (SetFlavorChoice,)
-
- def format_status_message(self, message):
- return message % self.context.get('name', 'unknown instance')
-
- @sensitive_variables('context')
- def handle(self, request, context):
- instance_id = context.get('instance_id', None)
- flavor = context.get('flavor', None)
- try:
- api.nova.server_resize(request, instance_id, flavor)
- return True
- except:
- exceptions.handle(request)
- return False
diff --git a/openstack_dashboard/dashboards/project/instances/workflows/update_instance.py b/openstack_dashboard/dashboards/project/instances/workflows/update_instance.py
deleted file mode 100644
index f4cc5b9b..00000000
--- a/openstack_dashboard/dashboards/project/instances/workflows/update_instance.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import workflows
-
-from openstack_dashboard import api
-from openstack_dashboard.utils.filters import get_int_or_uuid
-
-
-INDEX_URL = "horizon:projects:instances:index"
-ADD_USER_URL = "horizon:projects:instances:create_user"
-
-
-class UpdateInstanceSecurityGroupsAction(workflows.Action):
- default_role = forms.CharField(required=False)
- role_member = forms.MultipleChoiceField(required=False)
-
- def __init__(self, request, *args, **kwargs):
- super(UpdateInstanceSecurityGroupsAction, self).__init__(request,
- *args,
- **kwargs)
- err_msg = _('Unable to retrieve security group list. '
- 'Please try again later.')
- context = args[0]
- instance_id = context.get('instance_id', '')
-
- self.fields['default_role'].initial = 'member'
-
- # Get list of available security groups
- all_groups = []
- try:
- all_groups = api.network.security_group_list(request)
- except:
- exceptions.handle(request, err_msg)
- groups_list = [(group.id, group.name) for group in all_groups]
-
- instance_groups = []
- try:
- instance_groups = api.network.server_security_groups(request,
- instance_id)
- except Exception:
- exceptions.handle(request, err_msg)
- self.fields['role_member'].choices = groups_list
- self.fields['role_member'].initial = [group.id
- for group in instance_groups]
-
- def handle(self, request, data):
- instance_id = data['instance_id']
- wanted_groups = map(get_int_or_uuid, data['wanted_groups'])
- try:
- api.network.server_update_security_groups(request, instance_id,
- wanted_groups)
- except Exception as e:
- exceptions.handle(request, e.message)
- return False
- return True
-
- class Meta:
- name = _("Security Groups")
- slug = "update_security_groups"
-
-
-class UpdateInstanceSecurityGroups(workflows.UpdateMembersStep):
- action_class = UpdateInstanceSecurityGroupsAction
- help_text = _("From here you can add and remove security groups to "
- "this project from the list of available security groups.")
- available_list_title = _("All Security Groups")
- members_list_title = _("Instance Security Groups")
- no_available_text = _("No security groups found.")
- no_members_text = _("No security groups enabled.")
- show_roles = False
- depends_on = ("instance_id",)
- contributes = ("wanted_groups",)
-
- def contribute(self, data, context):
- request = self.workflow.request
- if data:
- context["wanted_groups"] = request.POST.getlist("role_member")
- return context
-
-
-class UpdateInstanceInfoAction(workflows.Action):
- name = forms.CharField(required=True)
-
- def handle(self, request, data):
- try:
- api.nova.server_update(request,
- data['instance_id'],
- data['name'])
- except:
- exceptions.handle(request, ignore=True)
- return False
- return True
-
- class Meta:
- name = _("Info")
- slug = 'instance_info'
- help_text = _("From here you can edit the instance details.")
-
-
-class UpdateInstanceInfo(workflows.Step):
- action_class = UpdateInstanceInfoAction
- depends_on = ("instance_id",)
- contributes = ("name",)
-
-
-class UpdateInstance(workflows.Workflow):
- slug = "update_instance"
- name = _("Edit Instance")
- finalize_button_name = _("Save")
- success_message = _('Modified instance "%s".')
- failure_message = _('Unable to modify instance "%s".')
- success_url = "horizon:project:instances:index"
- default_steps = (UpdateInstanceInfo,
- UpdateInstanceSecurityGroups)
-
- def format_status_message(self, message):
- return message % self.context.get('name', 'unknown instance')
-
-
-# NOTE(kspear): nova doesn't support instance security group management
-# by an admin. This isn't really the place for this code,
-# but the other ways of special-casing this are even messier.
-class AdminUpdateInstance(UpdateInstance):
- success_url = "horizon:admin:instances:index"
- default_steps = (UpdateInstanceInfo,)
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/__init__.py b/openstack_dashboard/dashboards/project/loadbalancers/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/forms.py b/openstack_dashboard/dashboards/project/loadbalancers/forms.py
deleted file mode 100644
index 326560dd..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/forms.py
+++ /dev/null
@@ -1,246 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013, Mirantis Inc
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-# @author: Tatiana Mazur
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class UpdatePool(forms.SelfHandlingForm):
- name = forms.CharField(max_length=80, label=_("Name"))
- pool_id = forms.CharField(label=_("ID"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- description = forms.CharField(required=False,
- max_length=80, label=_("Description"))
- lb_method = forms.ChoiceField(label=_("Load Balancing Method"))
- admin_state_up = forms.BooleanField(label=_("Admin State"), required=False)
-
- failure_url = 'horizon:project:loadbalancers:index'
-
- def __init__(self, request, *args, **kwargs):
- super(UpdatePool, self).__init__(request, *args, **kwargs)
-
- lb_method_choices = [('ROUND_ROBIN', 'ROUND_ROBIN'),
- ('LEAST_CONNECTIONS', 'LEAST_CONNECTIONS'),
- ('SOURCE_IP', 'SOURCE_IP')]
- self.fields['lb_method'].choices = lb_method_choices
-
- def handle(self, request, context):
- try:
- data = {'pool': {'name': context['name'],
- 'description': context['description'],
- 'lb_method': context['lb_method'],
- 'admin_state_up': context['admin_state_up'],
- }}
- pool = api.lbaas.pool_update(request, context['pool_id'], **data)
- msg = _('Pool %s was successfully updated.') % context['name']
- LOG.debug(msg)
- messages.success(request, msg)
- return pool
- except:
- msg = _('Failed to update pool %s') % context['name']
- LOG.info(msg)
- redirect = reverse(self.failure_url)
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class UpdateVip(forms.SelfHandlingForm):
- name = forms.CharField(max_length=80, label=_("Name"))
- vip_id = forms.CharField(label=_("ID"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- description = forms.CharField(required=False,
- max_length=80, label=_("Description"))
- pool_id = forms.ChoiceField(label=_("Pool"))
- session_persistence = forms.ChoiceField(
- required=False, initial={}, label=_("Session Persistence"))
-
- cookie_name = forms.CharField(
- initial="", required=False,
- max_length=80, label=_("Cookie Name"),
- help_text=_("Required for APP_COOKIE persistence;"
- " Ignored otherwise."))
-
- connection_limit = forms.IntegerField(
- min_value=-1, label=_("Connection Limit"),
- help_text=_("Maximum number of connections allowed "
- "for the VIP or '-1' if the limit is not set"))
- admin_state_up = forms.BooleanField(label=_("Admin State"), required=False)
-
- failure_url = 'horizon:project:loadbalancers:index'
-
- def __init__(self, request, *args, **kwargs):
- super(UpdateVip, self).__init__(request, *args, **kwargs)
-
- pool_id_choices = []
- try:
- pools = api.lbaas.pools_get(request)
- except:
- pools = []
- exceptions.handle(request,
- _('Unable to retrieve pools list.'))
- pools = sorted(pools,
- key=lambda pool: pool.name)
- for p in pools:
- if (p.vip_id is None) or (p.id == kwargs['initial']['pool_id']):
- pool_id_choices.append((p.id, p.name))
- self.fields['pool_id'].choices = pool_id_choices
-
- session_persistence_choices = []
- for mode in ('SOURCE_IP', 'HTTP_COOKIE', 'APP_COOKIE'):
- session_persistence_choices.append((mode, mode))
- self.fields[
- 'session_persistence'].choices = session_persistence_choices
-
- def handle(self, request, context):
- if context['session_persistence']:
- stype = context['session_persistence']
- if stype == 'APP_COOKIE':
- cookie = context['cookie_name']
- context['session_persistence'] = {'type': stype,
- 'cookie_name': cookie}
- else:
- context['session_persistence'] = {'type': stype}
- else:
- context['session_persistence'] = {}
-
- try:
- data = {'vip': {'name': context['name'],
- 'description': context['description'],
- 'pool_id': context['pool_id'],
- 'session_persistence':
- context['session_persistence'],
- 'connection_limit': context['connection_limit'],
- 'admin_state_up': context['admin_state_up'],
- }}
- vip = api.lbaas.vip_update(request, context['vip_id'], **data)
- msg = _('VIP %s was successfully updated.') % context['name']
- LOG.debug(msg)
- messages.success(request, msg)
- return vip
- except:
- msg = _('Failed to update VIP %s') % context['name']
- LOG.info(msg)
- redirect = reverse(self.failure_url)
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class UpdateMember(forms.SelfHandlingForm):
- member_id = forms.CharField(label=_("ID"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- pool_id = forms.ChoiceField(label=_("Pool"))
- weight = forms.IntegerField(max_value=256, min_value=0, label=_("Weight"),
- help_text=_("Relative part of requests this "
- "pool member serves compared to others"))
- admin_state_up = forms.BooleanField(label=_("Admin State"), required=False)
-
- failure_url = 'horizon:project:loadbalancers:index'
-
- def __init__(self, request, *args, **kwargs):
- super(UpdateMember, self).__init__(request, *args, **kwargs)
-
- pool_id_choices = []
- try:
- pools = api.lbaas.pools_get(request)
- except:
- pools = []
- exceptions.handle(request,
- _('Unable to retrieve pools list.'))
- pools = sorted(pools,
- key=lambda pool: pool.name)
- for p in pools:
- pool_id_choices.append((p.id, p.name))
- self.fields['pool_id'].choices = pool_id_choices
-
- def handle(self, request, context):
- try:
- data = {'member': {'pool_id': context['pool_id'],
- 'weight': context['weight'],
- 'admin_state_up': context['admin_state_up']}}
- member = api.lbaas.member_update(request,
- context['member_id'], **data)
- msg = _('Member %s was successfully updated.')\
- % context['member_id']
- LOG.debug(msg)
- messages.success(request, msg)
- return member
- except:
- msg = _('Failed to update member %s') % context['member_id']
- LOG.info(msg)
- redirect = reverse(self.failure_url)
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class UpdateMonitor(forms.SelfHandlingForm):
- monitor_id = forms.CharField(label=_("ID"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- delay = forms.IntegerField(
- min_value=1,
- label=_("Delay"),
- help_text=_("The minimum time in seconds between regular checks "
- "of a member"))
- timeout = forms.IntegerField(
- min_value=1,
- label=_("Timeout"),
- help_text=_("The maximum time in seconds for a monitor to wait "
- "for a reply"))
- max_retries = forms.IntegerField(
- max_value=10, min_value=1,
- label=_("Max Retries (1~10)"),
- help_text=_("Number of permissible failures before changing "
- "the status of member to inactive"))
- admin_state_up = forms.BooleanField(label=_("Admin State"), required=False)
-
- failure_url = 'horizon:project:loadbalancers:index'
-
- def __init__(self, request, *args, **kwargs):
- super(UpdateMonitor, self).__init__(request, *args, **kwargs)
-
- def handle(self, request, context):
- try:
- data = {'health_monitor': {
- 'delay': context['delay'],
- 'timeout': context['timeout'],
- 'max_retries': context['max_retries'],
- 'admin_state_up': context['admin_state_up']}}
- monitor = api.lbaas.pool_health_monitor_update(request,
- context['monitor_id'], **data)
- msg = _('Health monitor %s was successfully updated.')\
- % context['monitor_id']
- LOG.debug(msg)
- messages.success(request, msg)
- return monitor
- except:
- msg = _('Failed to update health monitor %s')\
- % context['monitor_id']
- LOG.info(msg)
- redirect = reverse(self.failure_url)
- exceptions.handle(request, msg, redirect=redirect)
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/models.py b/openstack_dashboard/dashboards/project/loadbalancers/models.py
deleted file mode 100644
index 1b3d5f9e..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/panel.py b/openstack_dashboard/dashboards/project/loadbalancers/panel.py
deleted file mode 100644
index 30773224..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/panel.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.project import dashboard
-
-
-class LoadBalancer(horizon.Panel):
- name = _("Load Balancers")
- slug = "loadbalancers"
- permissions = ('openstack.services.network',)
-
-
-network_config = (
- getattr(settings, 'OPENSTACK_NEUTRON_NETWORK', {}) or
- getattr(settings, 'OPENSTACK_QUANTUM_NETWORK', {})
-)
-
-if network_config.get('enable_lb'):
- dashboard.Project.register(LoadBalancer)
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/tables.py b/openstack_dashboard/dashboards/project/loadbalancers/tables.py
deleted file mode 100644
index 79e7865e..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/tables.py
+++ /dev/null
@@ -1,243 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013, Big Switch Networks, 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.core.urlresolvers import reverse
-from django.utils import http
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-
-from openstack_dashboard import api
-
-import logging
-
-
-LOG = logging.getLogger(__name__)
-
-
-class AddPoolLink(tables.LinkAction):
- name = "addpool"
- verbose_name = _("Add Pool")
- url = "horizon:project:loadbalancers:addpool"
- classes = ("ajax-modal", "btn-create",)
-
-
-class AddVipLink(tables.LinkAction):
- name = "addvip"
- verbose_name = _("Add VIP")
- classes = ("ajax-modal", "btn-create",)
-
- def get_link_url(self, pool):
- base_url = reverse("horizon:project:loadbalancers:addvip",
- kwargs={'pool_id': pool.id})
- return base_url
-
- def allowed(self, request, datum=None):
- if datum and datum.vip_id:
- return False
- return True
-
-
-class AddMemberLink(tables.LinkAction):
- name = "addmember"
- verbose_name = _("Add Member")
- url = "horizon:project:loadbalancers:addmember"
- classes = ("ajax-modal", "btn-create",)
-
-
-class AddMonitorLink(tables.LinkAction):
- name = "addmonitor"
- verbose_name = _("Add Monitor")
- url = "horizon:project:loadbalancers:addmonitor"
- classes = ("ajax-modal", "btn-create",)
-
-
-class DeleteVipLink(tables.DeleteAction):
- name = "deletevip"
- action_present = _("Delete")
- action_past = _("Scheduled deletion of")
- data_type_singular = _("VIP")
- data_type_plural = _("VIPs")
-
- def allowed(self, request, datum=None):
- if datum and not datum.vip_id:
- return False
- return True
-
-
-class DeletePoolLink(tables.DeleteAction):
- name = "deletepool"
- action_present = _("Delete")
- action_past = _("Scheduled deletion of")
- data_type_singular = _("Pool")
- data_type_plural = _("Pools")
-
-
-class DeleteMonitorLink(tables.DeleteAction):
- name = "deletemonitor"
- action_present = _("Delete")
- action_past = _("Scheduled deletion of")
- data_type_singular = _("Monitor")
- data_type_plural = _("Monitors")
-
-
-class DeleteMemberLink(tables.DeleteAction):
- name = "deletemember"
- action_present = _("Delete")
- action_past = _("Scheduled deletion of")
- data_type_singular = _("Member")
- data_type_plural = _("Members")
-
-
-class UpdatePoolLink(tables.LinkAction):
- name = "updatepool"
- verbose_name = _("Edit Pool")
- classes = ("btn-update",)
-
- def get_link_url(self, pool):
- base_url = reverse("horizon:project:loadbalancers:updatepool",
- kwargs={'pool_id': pool.id})
- return base_url
-
-
-class UpdateVipLink(tables.LinkAction):
- name = "updatevip"
- verbose_name = _("Edit VIP")
-
- def get_link_url(self, pool):
- base_url = reverse("horizon:project:loadbalancers:updatevip",
- kwargs={'vip_id': pool.vip_id})
- return base_url
-
- def allowed(self, request, datum=None):
- if datum and not datum.vip_id:
- return False
- return True
-
-
-class UpdateMemberLink(tables.LinkAction):
- name = "updatemember"
- verbose_name = _("Edit Member")
-
- def get_link_url(self, member):
- base_url = reverse("horizon:project:loadbalancers:updatemember",
- kwargs={'member_id': member.id})
- return base_url
-
-
-class UpdateMonitorLink(tables.LinkAction):
- name = "updatemonitor"
- verbose_name = _("Edit Monitor")
-
- def get_link_url(self, monitor):
- base_url = reverse("horizon:project:loadbalancers:updatemonitor",
- kwargs={'monitor_id': monitor.id})
- return base_url
-
-
-def get_vip_link(pool):
- return reverse("horizon:project:loadbalancers:vipdetails",
- args=(http.urlquote(pool.vip_id),))
-
-
-class AddPMAssociationLink(tables.LinkAction):
- name = "addassociation"
- verbose_name = _("Add Health Monitor")
- url = "horizon:project:loadbalancers:addassociation"
-
- def allowed(self, request, datum=None):
- try:
- monitors = api.lbaas.pool_health_monitors_get(request)
- for m in monitors:
- if m.id not in datum['health_monitors']:
- return True
- except:
- exceptions.handle(request,
- _('Failed to retrieve health monitors.'))
- return False
-
-
-class DeletePMAssociationLink(tables.LinkAction):
- name = "deleteassociation"
- verbose_name = _("Delete Health Monitor")
- url = "horizon:project:loadbalancers:deleteassociation"
- classes = ("btn-delete", "btn-danger")
-
- def allowed(self, request, datum=None):
- if datum and not datum['health_monitors']:
- return False
- return True
-
-
-class PoolsTable(tables.DataTable):
- name = tables.Column("name",
- verbose_name=_("Name"),
- link="horizon:project:loadbalancers:pooldetails")
- description = tables.Column('description', verbose_name=_("Description"))
- subnet_name = tables.Column('subnet_name', verbose_name=_("Subnet"))
- protocol = tables.Column('protocol', verbose_name=_("Protocol"))
- vip_name = tables.Column('vip_name', verbose_name=_("VIP"),
- link=get_vip_link)
-
- class Meta:
- name = "poolstable"
- verbose_name = _("Pools")
- table_actions = (AddPoolLink, DeletePoolLink)
- row_actions = (UpdatePoolLink, AddVipLink, UpdateVipLink,
- DeleteVipLink, AddPMAssociationLink,
- DeletePMAssociationLink, DeletePoolLink)
-
-
-def get_pool_link(member):
- return reverse("horizon:project:loadbalancers:pooldetails",
- args=(http.urlquote(member.pool_id),))
-
-
-def get_member_link(member):
- return reverse("horizon:project:loadbalancers:memberdetails",
- args=(http.urlquote(member.id),))
-
-
-class MembersTable(tables.DataTable):
- address = tables.Column('address',
- verbose_name=_("IP Address"),
- link=get_member_link,
- attrs={'data-type': "ip"})
- protocol_port = tables.Column('protocol_port',
- verbose_name=_("Protocol Port"))
- pool_name = tables.Column("pool_name",
- verbose_name=_("Pool"), link=get_pool_link)
-
- class Meta:
- name = "memberstable"
- verbose_name = _("Members")
- table_actions = (AddMemberLink, DeleteMemberLink)
- row_actions = (UpdateMemberLink, DeleteMemberLink)
-
-
-class MonitorsTable(tables.DataTable):
- id = tables.Column("id",
- verbose_name=_("ID"),
- link="horizon:project:loadbalancers:monitordetails")
- monitorType = tables.Column('type', verbose_name=_("Monitor Type"))
-
- class Meta:
- name = "monitorstable"
- verbose_name = _("Monitors")
- table_actions = (AddMonitorLink, DeleteMonitorLink)
- row_actions = (UpdateMonitorLink, DeleteMonitorLink)
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/tabs.py b/openstack_dashboard/dashboards/project/loadbalancers/tabs.py
deleted file mode 100644
index 0b816447..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/tabs.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013, Big Switch Networks, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.project.loadbalancers.tables \
- import MembersTable
-from openstack_dashboard.dashboards.project.loadbalancers.tables \
- import MonitorsTable
-from openstack_dashboard.dashboards.project.loadbalancers.tables \
- import PoolsTable
-
-
-class PoolsTab(tabs.TableTab):
- table_classes = (PoolsTable,)
- name = _("Pools")
- slug = "pools"
- template_name = "horizon/common/_detail_table.html"
-
- def get_poolstable_data(self):
- try:
- pools = api.lbaas.pools_get(self.tab_group.request)
- poolsFormatted = [p.readable(self.tab_group.request) for
- p in pools]
- except:
- poolsFormatted = []
- exceptions.handle(self.tab_group.request,
- _('Unable to retrieve pools list.'))
- return poolsFormatted
-
-
-class MembersTab(tabs.TableTab):
- table_classes = (MembersTable,)
- name = _("Members")
- slug = "members"
- template_name = "horizon/common/_detail_table.html"
-
- def get_memberstable_data(self):
- try:
- members = api.lbaas.members_get(self.tab_group.request)
- membersFormatted = [m.readable(self.tab_group.request) for
- m in members]
- except:
- membersFormatted = []
- exceptions.handle(self.tab_group.request,
- _('Unable to retrieve member list.'))
- return membersFormatted
-
-
-class MonitorsTab(tabs.TableTab):
- table_classes = (MonitorsTable,)
- name = _("Monitors")
- slug = "monitors"
- template_name = "horizon/common/_detail_table.html"
-
- def get_monitorstable_data(self):
- try:
- monitors = api.lbaas.pool_health_monitors_get(
- self.tab_group.request)
- except:
- monitors = []
- exceptions.handle(self.tab_group.request,
- _('Unable to retrieve monitor list.'))
- return monitors
-
-
-class LoadBalancerTabs(tabs.TabGroup):
- slug = "lbtabs"
- tabs = (PoolsTab, MembersTab, MonitorsTab)
- sticky = True
-
-
-class PoolDetailsTab(tabs.Tab):
- name = _("Pool Details")
- slug = "pooldetails"
- template_name = "project/loadbalancers/_pool_details.html"
-
- def get_context_data(self, request):
- pid = self.tab_group.kwargs['pool_id']
- try:
- pool = api.lbaas.pool_get(request, pid)
- except:
- pool = []
- exceptions.handle(request,
- _('Unable to retrieve pool details.'))
- return {'pool': pool}
-
-
-class VipDetailsTab(tabs.Tab):
- name = _("VIP Details")
- slug = "vipdetails"
- template_name = "project/loadbalancers/_vip_details.html"
-
- def get_context_data(self, request):
- vid = self.tab_group.kwargs['vip_id']
- try:
- vip = api.lbaas.vip_get(request, vid)
- except:
- vip = []
- exceptions.handle(self.tab_group.request,
- _('Unable to retrieve VIP details.'))
- return {'vip': vip}
-
-
-class MemberDetailsTab(tabs.Tab):
- name = _("Member Details")
- slug = "memberdetails"
- template_name = "project/loadbalancers/_member_details.html"
-
- def get_context_data(self, request):
- mid = self.tab_group.kwargs['member_id']
- try:
- member = api.lbaas.member_get(request, mid)
- except:
- member = []
- exceptions.handle(self.tab_group.request,
- _('Unable to retrieve member details.'))
- return {'member': member}
-
-
-class MonitorDetailsTab(tabs.Tab):
- name = _("Monitor Details")
- slug = "monitordetails"
- template_name = "project/loadbalancers/_monitor_details.html"
-
- def get_context_data(self, request):
- mid = self.tab_group.kwargs['monitor_id']
- try:
- monitor = api.lbaas.pool_health_monitor_get(request, mid)
- except:
- monitor = []
- exceptions.handle(self.tab_group.request,
- _('Unable to retrieve monitor details.'))
- return {'monitor': monitor}
-
-
-class PoolDetailsTabs(tabs.TabGroup):
- slug = "pooltabs"
- tabs = (PoolDetailsTab,)
-
-
-class VipDetailsTabs(tabs.TabGroup):
- slug = "viptabs"
- tabs = (VipDetailsTab,)
-
-
-class MemberDetailsTabs(tabs.TabGroup):
- slug = "membertabs"
- tabs = (MemberDetailsTab,)
-
-
-class MonitorDetailsTabs(tabs.TabGroup):
- slug = "monitortabs"
- tabs = (MonitorDetailsTab,)
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html
deleted file mode 100644
index 68b12067..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{% load i18n sizeformat parse_date %}
-
-<div class="info row-fluid detail">
- <hr class="header_rule">
- <dl>
- <dt>{% trans "ID: " %}</dt>
- <dd>{{ member.id }}</dd>
-
- <dt>{% trans "Tenant ID: " %}</dt>
- <dd>{{ member.tenant_id }}</dd>
-
- <dt>{% trans "Pool ID: " %}</dt>
- <dd>{{ member.pool_id }}</dd>
-
- <dt>{% trans "Address: " %}</dt>
- <dd>{{ member.address }}</dd>
-
- <dt>{% trans "Protocol Port: " %}</dt>
- <dd>{{ member.protocol_port }}</dd>
-
- <dt>{% trans "Weight: " %}</dt>
- <dd>{{ member.weight }}</dd>
-
- <dt>{% trans "Admin State Up: " %}</dt>
- <dd>{{ member.admin_state_up }}</dd>
-
- <dt>{% trans "Status: " %}</dt>
- <dd>{{ member.status }}</dd>
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_members_tab.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_members_tab.html
deleted file mode 100644
index 7580cda4..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_members_tab.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% block main %}
-
- {{ table.render }}
-
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html
deleted file mode 100644
index b0668162..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html
+++ /dev/null
@@ -1,41 +0,0 @@
-{% load i18n sizeformat parse_date %}
-
-<div class="info row-fluid detail">
- <hr class="header_rule">
- <dl>
- <dt>{% trans "ID: " %}</dt>
- <dd>{{ monitor.id }}</dd>
-
- <dt>{% trans "Tenant ID: " %}</dt>
- <dd>{{ monitor.tenant_id }}</dd>
-
- <dt>{% trans "Type: " %}</dt>
- <dd>{{ monitor.type }}</dd>
-
- <dt>{% trans "Delay: " %}</dt>
- <dd>{{ monitor.delay }}</dd>
-
- <dt>{% trans "Timeout: " %}</dt>
- <dd>{{ monitor.timeout }}</dd>
-
- <dt>{% trans "Max Retries: " %}</dt>
- <dd>{{ monitor.max_retries }}</dd>
-
- {% if monitor.type == 'HTTP' or monitor.type == 'HTTPS' %}
- <dt>{% trans "HTTP Method: " %}</dt>
- <dd>{{ monitor.http_method }}</dd>
-
- <dt>{% trans "URL Path: " %}</dt>
- <dd>{{ monitor.url_path }}</dd>
-
- <dt>{% trans "Expected Codes: " %}</dt>
- <dd>{{ monitor.expected_codes }}</dd>
- {% endif %}
-
- <dt>{% trans "Admin State Up: " %}</dt>
- <dd>{{ monitor.admin_state_up }}</dd>
-
- <dt>{% trans "Status: " %}</dt>
- <dd>{{ monitor.status }}</dd>
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_monitors_tab.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_monitors_tab.html
deleted file mode 100644
index 7580cda4..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_monitors_tab.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% block main %}
-
- {{ table.render }}
-
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html
deleted file mode 100644
index b8918abf..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html
+++ /dev/null
@@ -1,42 +0,0 @@
-{% load i18n sizeformat parse_date %}
-
-<div class="info row-fluid detail">
- <hr class="header_rule">
- <dl>
- <dt>{% trans "ID: " %}</dt>
- <dd>{{ pool.id }}</dd>
-
- <dt>{% trans "Tenant ID: " %}</dt>
- <dd>{{ pool.tenant_id }}</dd>
-
- <dt>{% trans "VIP ID: " %}</dt>
- <dd>{{ pool.vip_id }}</dd>
-
- <dt>{% trans "Name: " %}</dt>
- <dd>{{ pool.name }}</dd>
-
- <dt>{% trans "Description: " %}</dt>
- <dd>{{ pool.description }}</dd>
-
- <dt>{% trans "Subnet ID: " %}</dt>
- <dd>{{ pool.subnet_id }}</dd>
-
- <dt>{% trans "Protocol: " %}</dt>
- <dd>{{ pool.protocol }}</dd>
-
- <dt>{% trans "Load Balancing Method: " %}</dt>
- <dd>{{ pool.lb_method }}</dd>
-
- <dt>{% trans "Members: " %}</dt>
- <dd>{{ pool.members }}</dd>
-
- <dt>{% trans "Health Monitors: " %}</dt>
- <dd>{{ pool.health_monitors }}</dd>
-
- <dt>{% trans "Admin State Up: " %}</dt>
- <dd>{{ pool.admin_state_up }}</dd>
-
- <dt>{% trans "Status: " %}</dt>
- <dd>{{ pool.status }}</dd>
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_pools_tab.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_pools_tab.html
deleted file mode 100644
index da23734d..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_pools_tab.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% block main %}
-
- {{ poolstable.render }}
-
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatemember.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatemember.html
deleted file mode 100644
index 8acd393b..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatemember.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_pool_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:loadbalancers:updatemember' member_id %}{% endblock %}
-
-{% block modal-header %}{% trans "Edit Member" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "You may update member attributes here: edit pool, weight or admin state." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
- <a href="{% url 'horizon:project:loadbalancers:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %} \ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatemonitor.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatemonitor.html
deleted file mode 100644
index 4ab1148c..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatemonitor.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_monitor_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:loadbalancers:updatemonitor' monitor_id %}{% endblock %}
-
-{% block modal-header %}{% trans "Edit Monitor" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "You may update health monitor attributes here: edit delay, timeout, max retries or admin state." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
- <a href="{% url 'horizon:project:loadbalancers:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatepool.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatepool.html
deleted file mode 100644
index 567850c2..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatepool.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_pool_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:loadbalancers:updatepool' pool_id %}{% endblock %}
-
-{% block modal-header %}{% trans "Edit Pool" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "You may update pool for current tenant here: edit name, description, load balancing method or admin state." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
- <a href="{% url 'horizon:project:loadbalancers:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatevip.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatevip.html
deleted file mode 100644
index d7097a40..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_updatevip.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_vip_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:loadbalancers:updatevip' vip_id %}{% endblock %}
-
-{% block modal-header %}{% trans "Edit VIP" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "You may update VIP attributes here: edit name, description, pool, session persistence, connection limit or admin state." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
- <a href="{% url 'horizon:project:loadbalancers:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html
deleted file mode 100644
index e56b3dee..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html
+++ /dev/null
@@ -1,48 +0,0 @@
-{% load i18n sizeformat parse_date %}
-
-<div class="info row-fluid detail">
- <hr class="header_rule">
- <dl>
- <dt>{% trans "ID: " %}</dt>
- <dd>{{ vip.id }}</dd>
-
- <dt>{% trans "Tenant ID: " %}</dt>
- <dd>{{ vip.tenant_id }}</dd>
-
- <dt>{% trans "Name: " %}</dt>
- <dd>{{ vip.name }}</dd>
-
- <dt>{% trans "Description: " %}</dt>
- <dd>{{ vip.description }}</dd>
-
- <dt>{% trans "Subnet ID: " %}</dt>
- <dd>{{ vip.subnet_id }}</dd>
-
- <dt>{% trans "Address: " %}</dt>
- <dd>{{ vip.address }}</dd>
-
- <dt>{% trans "Protocol Port: " %}</dt>
- <dd>{{ vip.protocol_port }}</dd>
-
- <dt>{% trans "Protocol: " %}</dt>
- <dd>{{ vip.protocol }}</dd>
-
- <dt>{% trans "Pool ID: " %}</dt>
- <dd>{{ vip.pool_id }}</dd>
-
- <dt>{% trans "Session Persistence: " %}</dt>
- <dd>{% trans "Type: " %}{{ vip.session_persistence.type }}</dd>
- {% if vip.session_persistence.cookie_name %}
- <dd>{% trans "Cookie Name: " %}{{ vip.session_persistence.cookie_name }}</dd>
- {% endif %}
-
- <dt>{% trans "Connection Limit: " %}</dt>
- <dd>{{ vip.connection_limit }}</dd>
-
- <dt>{% trans "Admin State Up: " %}</dt>
- <dd>{{ vip.admin_state_up }}</dd>
-
- <dt>{% trans "Status: " %}</dt>
- <dd>{{ vip.status }}</dd>
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html
deleted file mode 100644
index 17ee96ca..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Load Balancer" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Load Balancer") %}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatemember.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatemember.html
deleted file mode 100644
index 9a235f87..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatemember.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Edit Member" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Edit Member") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/loadbalancers/_updatemember.html' %}
-{% endblock %} \ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatemonitor.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatemonitor.html
deleted file mode 100644
index e58a1330..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatemonitor.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Edit Monitor" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Edit Monitor") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/loadbalancers/_updatemonitor.html' %}
-{% endblock %} \ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatepool.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatepool.html
deleted file mode 100644
index 64455622..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatepool.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Edit Pool" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Edit Pool") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/loadbalancers/_updatepool.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatevip.html b/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatevip.html
deleted file mode 100644
index eb2ec357..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/templates/loadbalancers/updatevip.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Edit VIP" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Edit VIP") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/loadbalancers/_updatevip.html' %}
-{% endblock %} \ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/tests.py b/openstack_dashboard/dashboards/project/loadbalancers/tests.py
deleted file mode 100644
index 872fe0c0..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/tests.py
+++ /dev/null
@@ -1,794 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-from mox import IsA
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django import http
-
-from horizon.workflows.views import WorkflowView
-
-from openstack_dashboard import api
-from openstack_dashboard.api.lbaas import Member
-from openstack_dashboard.api.lbaas import Pool
-from openstack_dashboard.api.lbaas import PoolMonitor
-from openstack_dashboard.api.lbaas import Vip
-from openstack_dashboard.test import helpers as test
-
-from openstack_dashboard.dashboards.project.loadbalancers.workflows \
- import AddMember
-from openstack_dashboard.dashboards.project.loadbalancers.workflows \
- import AddMonitor
-from openstack_dashboard.dashboards.project.loadbalancers.workflows \
- import AddPMAssociation
-from openstack_dashboard.dashboards.project.loadbalancers.workflows \
- import AddPool
-from openstack_dashboard.dashboards.project.loadbalancers.workflows \
- import AddVip
-from openstack_dashboard.dashboards.project.loadbalancers.workflows \
- import DeletePMAssociation
-
-
-class LoadBalancerTests(test.TestCase):
- class AttributeDict(dict):
- def __getattr__(self, attr):
- return self[attr]
-
- def __setattr__(self, attr, value):
- self[attr] = value
-
- DASHBOARD = 'project'
- INDEX_URL = reverse_lazy('horizon:%s:loadbalancers:index' % DASHBOARD)
-
- ADDPOOL_PATH = 'horizon:%s:loadbalancers:addpool' % DASHBOARD
- ADDVIP_PATH = 'horizon:%s:loadbalancers:addvip' % DASHBOARD
- ADDMEMBER_PATH = 'horizon:%s:loadbalancers:addmember' % DASHBOARD
- ADDMONITOR_PATH = 'horizon:%s:loadbalancers:addmonitor' % DASHBOARD
-
- POOL_DETAIL_PATH = 'horizon:%s:loadbalancers:pooldetails' % DASHBOARD
- VIP_DETAIL_PATH = 'horizon:%s:loadbalancers:vipdetails' % DASHBOARD
- MEMBER_DETAIL_PATH = 'horizon:%s:loadbalancers:memberdetails' % DASHBOARD
- MONITOR_DETAIL_PATH = 'horizon:%s:loadbalancers:monitordetails' % DASHBOARD
-
- UPDATEPOOL_PATH = 'horizon:%s:loadbalancers:updatepool' % DASHBOARD
- UPDATEVIP_PATH = 'horizon:%s:loadbalancers:updatevip' % DASHBOARD
- UPDATEMEMBER_PATH = 'horizon:%s:loadbalancers:updatemember' % DASHBOARD
- UPDATEMONITOR_PATH = 'horizon:%s:loadbalancers:updatemonitor' % DASHBOARD
-
- ADDASSOC_PATH = 'horizon:%s:loadbalancers:addassociation' % DASHBOARD
- DELETEASSOC_PATH = 'horizon:%s:loadbalancers:deleteassociation' % DASHBOARD
-
- def set_up_expect(self):
- # retrieve pools
- vip1 = self.vips.first()
-
- vip2 = self.vips.list()[1]
-
- api.lbaas.pools_get(
- IsA(http.HttpRequest)).AndReturn(self.pools.list())
-
- api.lbaas.vip_get(IsA(http.HttpRequest), vip1.id).AndReturn(vip1)
- api.lbaas.vip_get(IsA(http.HttpRequest), vip2.id).AndReturn(vip2)
-
- # retrieves members
- api.lbaas.members_get(
- IsA(http.HttpRequest)).AndReturn(self.members.list())
-
- pool1 = self.pools.first()
- pool2 = self.pools.list()[1]
-
- api.lbaas.pool_get(IsA(http.HttpRequest),
- self.members.list()[0].pool_id).AndReturn(pool1)
- api.lbaas.pool_get(IsA(http.HttpRequest),
- self.members.list()[1].pool_id).AndReturn(pool2)
-
- # retrieves monitors
- api.lbaas.pool_health_monitors_get(
- IsA(http.HttpRequest)).MultipleTimes() \
- .AndReturn(self.monitors.list())
-
- def set_up_expect_with_exception(self):
- api.lbaas.pools_get(
- IsA(http.HttpRequest)).AndRaise(self.exceptions.neutron)
- api.lbaas.members_get(
- IsA(http.HttpRequest)).AndRaise(self.exceptions.neutron)
- api.lbaas.pool_health_monitors_get(
- IsA(http.HttpRequest)).AndRaise(self.exceptions.neutron)
-
- @test.create_stubs({api.lbaas: ('pools_get', 'vip_get',
- 'members_get', 'pool_get',
- 'pool_health_monitors_get'),
- api.neutron: ('subnet_get',)})
- def test_index_pools(self):
- self.set_up_expect()
-
- self.mox.ReplayAll()
-
- res = self.client.get(self.INDEX_URL)
-
- self.assertTemplateUsed(res, '%s/loadbalancers/details_tabs.html'
- % self.DASHBOARD)
- self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
- self.assertEqual(len(res.context['table'].data),
- len(self.pools.list()))
-
- @test.create_stubs({api.lbaas: ('pools_get', 'vip_get',
- 'members_get', 'pool_get',
- 'pool_health_monitors_get'),
- api.neutron: ('subnet_get',)})
- def test_index_members(self):
- self.set_up_expect()
-
- self.mox.ReplayAll()
-
- res = self.client.get(self.INDEX_URL + '?tab=lbtabs__members')
-
- self.assertTemplateUsed(res, '%s/loadbalancers/details_tabs.html'
- % self.DASHBOARD)
- self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
- self.assertEqual(len(res.context['memberstable_table'].data),
- len(self.members.list()))
-
- @test.create_stubs({api.lbaas: ('pools_get', 'vip_get',
- 'pool_health_monitors_get',
- 'members_get', 'pool_get'),
- api.neutron: ('subnet_get',)})
- def test_index_monitors(self):
- self.set_up_expect()
-
- self.mox.ReplayAll()
-
- res = self.client.get(self.INDEX_URL + '?tab=lbtabs__monitors')
-
- self.assertTemplateUsed(res, '%s/loadbalancers/details_tabs.html'
- % self.DASHBOARD)
- self.assertTemplateUsed(res, 'horizon/common/_detail_table.html')
- self.assertEqual(len(res.context['monitorstable_table'].data),
- len(self.monitors.list()))
-
- @test.create_stubs({api.lbaas: ('pools_get', 'members_get',
- 'pool_health_monitors_get')})
- def test_index_exception_pools(self):
- self.set_up_expect_with_exception()
-
- self.mox.ReplayAll()
-
- res = self.client.get(self.INDEX_URL)
-
- self.assertTemplateUsed(res,
- '%s/loadbalancers/details_tabs.html'
- % self.DASHBOARD)
- self.assertTemplateUsed(res,
- 'horizon/common/_detail_table.html')
- self.assertEqual(len(res.context['table'].data), 0)
-
- @test.create_stubs({api.lbaas: ('pools_get', 'members_get',
- 'pool_health_monitors_get')})
- def test_index_exception_members(self):
- self.set_up_expect_with_exception()
-
- self.mox.ReplayAll()
-
- res = self.client.get(self.INDEX_URL + '?tab=lbtabs__members')
-
- self.assertTemplateUsed(res,
- '%s/loadbalancers/details_tabs.html'
- % self.DASHBOARD)
- self.assertTemplateUsed(res,
- 'horizon/common/_detail_table.html')
- self.assertEqual(len(res.context['memberstable_table'].data), 0)
-
- @test.create_stubs({api.lbaas: ('pools_get', 'members_get',
- 'pool_health_monitors_get')})
- def test_index_exception_monitors(self):
- self.set_up_expect_with_exception()
-
- self.mox.ReplayAll()
-
- res = self.client.get(self.INDEX_URL + '?tab=lbtabs__monitors')
-
- self.assertTemplateUsed(res,
- '%s/loadbalancers/details_tabs.html'
- % self.DASHBOARD)
- self.assertTemplateUsed(res,
- 'horizon/common/_detail_table.html')
- self.assertEqual(len(res.context['monitorstable_table'].data), 0)
-
- @test.create_stubs({api.neutron: ('network_list_for_tenant',),
- api.lbaas: ('pool_create', )})
- def test_add_pool_post(self):
- pool = self.pools.first()
-
- subnet = self.subnets.first()
- networks = [{'subnets': [subnet, ]}, ]
-
- api.neutron.network_list_for_tenant(
- IsA(http.HttpRequest), subnet.tenant_id).AndReturn(networks)
-
- api.lbaas.pool_create(
- IsA(http.HttpRequest),
- name=pool.name,
- description=pool.description,
- subnet_id=pool.subnet_id,
- protocol=pool.protocol,
- lb_method=pool.lb_method,
- admin_state_up=pool.admin_state_up).AndReturn(Pool(pool))
-
- self.mox.ReplayAll()
-
- form_data = {'name': pool.name,
- 'description': pool.description,
- 'subnet_id': pool.subnet_id,
- 'protocol': pool.protocol,
- 'lb_method': pool.lb_method,
- 'admin_state_up': pool.admin_state_up}
-
- res = self.client.post(reverse(self.ADDPOOL_PATH), form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
-
- @test.create_stubs({api.neutron: ('network_list_for_tenant',)})
- def test_add_pool_get(self):
- subnet = self.subnets.first()
-
- networks = [{'subnets': [subnet, ]}, ]
-
- api.neutron.network_list_for_tenant(
- IsA(http.HttpRequest), subnet.tenant_id).AndReturn(networks)
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse(self.ADDPOOL_PATH))
-
- workflow = res.context['workflow']
- self.assertTemplateUsed(res, WorkflowView.template_name)
- self.assertEqual(workflow.name, AddPool.name)
-
- expected_objs = ['<AddPoolStep: addpoolaction>', ]
- self.assertQuerysetEqual(workflow.steps, expected_objs)
-
- @test.create_stubs({api.lbaas: ('pool_get', 'vip_create'),
- api.neutron: ('subnet_get', )})
- def test_add_vip_post(self):
- vip = self.vips.first()
-
- subnet = self.subnets.first()
- pool = self.pools.first()
-
- api.lbaas.pool_get(
- IsA(http.HttpRequest), pool.id).MultipleTimes().AndReturn(pool)
-
- api.neutron.subnet_get(
- IsA(http.HttpRequest), subnet.id).AndReturn(subnet)
-
- api.lbaas.vip_create(
- IsA(http.HttpRequest),
- name=vip.name,
- description=vip.description,
- pool_id=vip.pool_id,
- address=vip.address,
- floatip_address=vip.floatip_address,
- other_address=vip.other_address,
- subnet=vip.subnet,
- subnet_id=vip.subnet_id,
- protocol_port=vip.protocol_port,
- protocol=vip.protocol,
- session_persistence=vip.session_persistence['type'],
- cookie_name=vip.session_persistence['cookie_name'],
- connection_limit=vip.connection_limit,
- admin_state_up=vip.admin_state_up).AndReturn(Vip(vip))
-
- self.mox.ReplayAll()
-
- form_data = {'name': vip.name,
- 'description': vip.description,
- 'pool_id': vip.pool_id,
- 'address': vip.address,
- 'floatip_address': vip.floatip_address,
- 'other_address': vip.other_address,
- 'subnet_id': vip.subnet_id,
- 'subnet': vip.subnet,
- 'protocol_port': vip.protocol_port,
- 'protocol': vip.protocol,
- 'session_persistence': vip.session_persistence['type'],
- 'cookie_name': vip.session_persistence['cookie_name'],
- 'connection_limit': vip.connection_limit,
- 'admin_state_up': vip.admin_state_up}
-
- res = self.client.post(
- reverse(self.ADDVIP_PATH, args=(pool.id,)), form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
-
- @test.create_stubs({api.lbaas: ('pool_get', ),
- api.neutron: ('subnet_get', )})
- def test_add_vip_post_with_error(self):
- vip = self.vips.first()
-
- subnet = self.subnets.first()
- pool = self.pools.first()
-
- api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).AndReturn(pool)
- api.neutron.subnet_get(
- IsA(http.HttpRequest), subnet.id).AndReturn(subnet)
-
- self.mox.ReplayAll()
-
- form_data = {'name': vip.name,
- 'description': vip.description,
- 'pool_id': vip.pool_id,
- 'address': vip.address,
- 'subnet_id': vip.subnet_id,
- 'protocol_port': 65536,
- 'protocol': vip.protocol,
- 'session_persistence': vip.session_persistence['type'],
- 'cookie_name': vip.session_persistence['cookie_name'],
- 'connection_limit': -2,
- 'admin_state_up': vip.admin_state_up}
-
- res = self.client.post(
- reverse(self.ADDVIP_PATH, args=(pool.id,)), form_data)
-
- self.assertFormErrors(res, 2)
-
- @test.create_stubs({api.lbaas: ('pool_get', ),
- api.neutron: ('subnet_get', )})
- def test_add_vip_get(self):
- subnet = self.subnets.first()
- pool = self.pools.first()
-
- api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).AndReturn(pool)
- api.neutron.subnet_get(
- IsA(http.HttpRequest), subnet.id).AndReturn(subnet)
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse(self.ADDVIP_PATH, args=(pool.id,)))
-
- workflow = res.context['workflow']
- self.assertTemplateUsed(res, WorkflowView.template_name)
- self.assertEqual(workflow.name, AddVip.name)
-
- expected_objs = ['<AddVipStep: addvipaction>', ]
- self.assertQuerysetEqual(workflow.steps, expected_objs)
-
- @test.create_stubs({api.lbaas: ('pool_health_monitor_create', )})
- def test_add_monitor_post(self):
- monitor = self.monitors.first()
-
- api.lbaas.pool_health_monitor_create(
- IsA(http.HttpRequest),
- type=monitor.type,
- delay=monitor.delay,
- timeout=monitor.timeout,
- max_retries=monitor.max_retries,
- http_method=monitor.http_method,
- url_path=monitor.url_path,
- expected_codes=monitor.expected_codes,
- admin_state_up=monitor.admin_state_up).AndReturn(
- PoolMonitor(monitor))
-
- self.mox.ReplayAll()
-
- form_data = {'type': monitor.type,
- 'delay': monitor.delay,
- 'timeout': monitor.timeout,
- 'max_retries': monitor.max_retries,
- 'http_method': monitor.http_method,
- 'url_path': monitor.url_path,
- 'expected_codes': monitor.expected_codes,
- 'admin_state_up': monitor.admin_state_up}
-
- res = self.client.post(reverse(self.ADDMONITOR_PATH), form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
-
- def test_add_monitor_post_with_error(self):
- monitor = self.monitors.first()
-
- form_data = {'type': monitor.type,
- 'delay': 0,
- 'timeout': 0,
- 'max_retries': 11,
- 'http_method': monitor.http_method,
- 'url_path': monitor.url_path,
- 'expected_codes': monitor.expected_codes,
- 'admin_state_up': monitor.admin_state_up}
-
- res = self.client.post(reverse(self.ADDMONITOR_PATH), form_data)
-
- self.assertFormErrors(res, 3)
-
- def test_add_monitor_post_with_httpmethod_error(self):
- monitor = self.monitors.first()
-
- form_data = {'type': 'http',
- 'delay': monitor.delay,
- 'timeout': monitor.timeout,
- 'max_retries': monitor.max_retries,
- 'http_method': '',
- 'url_path': '',
- 'expected_codes': '',
- 'admin_state_up': monitor.admin_state_up}
-
- res = self.client.post(reverse(self.ADDMONITOR_PATH), form_data)
-
- self.assertFormErrors(res, 3)
-
- def test_add_monitor_get(self):
- res = self.client.get(reverse(self.ADDMONITOR_PATH))
-
- workflow = res.context['workflow']
- self.assertTemplateUsed(res, WorkflowView.template_name)
- self.assertEqual(workflow.name, AddMonitor.name)
-
- expected_objs = ['<AddMonitorStep: addmonitoraction>', ]
- self.assertQuerysetEqual(workflow.steps, expected_objs)
-
- @test.create_stubs({api.lbaas: ('pools_get', 'member_create'),
- api.neutron: ('port_list',),
- api.nova: ('server_list',)})
- def test_add_member_post(self):
- member = self.members.first()
-
- server1 = self.AttributeDict({'id':
- '12381d38-c3eb-4fee-9763-12de3338042e',
- 'name': 'vm1'})
- server2 = self.AttributeDict({'id':
- '12381d38-c3eb-4fee-9763-12de3338043e',
- 'name': 'vm2'})
-
- port1 = self.AttributeDict(
- {'fixed_ips': [{'ip_address': member.address}]})
-
- api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
-
- api.nova.server_list(IsA(http.HttpRequest)).AndReturn(
- [[server1, server2], False])
-
- api.neutron.port_list(IsA(http.HttpRequest),
- device_id=server1.id).AndReturn([port1, ])
-
- api.lbaas.member_create(
- IsA(http.HttpRequest),
- pool_id=member.pool_id,
- address=member.address,
- protocol_port=member.protocol_port,
- weight=member.weight,
- members=[server1.id],
- admin_state_up=member.admin_state_up).AndReturn(Member(member))
-
- self.mox.ReplayAll()
-
- form_data = {'pool_id': member.pool_id,
- 'address': member.address,
- 'protocol_port': member.protocol_port,
- 'weight': member.weight,
- 'members': [server1.id],
- 'admin_state_up': member.admin_state_up}
-
- res = self.client.post(reverse(self.ADDMEMBER_PATH), form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
-
- @test.create_stubs({api.lbaas: ('pools_get',),
- api.nova: ('server_list',)})
- def test_add_member_post_with_error(self):
- member = self.members.first()
-
- server1 = self.AttributeDict({'id':
- '12381d38-c3eb-4fee-9763-12de3338042e',
- 'name': 'vm1'})
- server2 = self.AttributeDict({'id':
- '12381d38-c3eb-4fee-9763-12de3338043e',
- 'name': 'vm2'})
-
- api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
-
- api.nova.server_list(IsA(http.HttpRequest)).AndReturn([[server1,
- server2],
- False])
-
- self.mox.ReplayAll()
-
- # try to create member with invalid protocol port and weight
- form_data = {'pool_id': member.pool_id,
- 'address': member.address,
- 'protocol_port': 65536,
- 'weight': -1,
- 'members': [server1.id],
- 'admin_state_up': member.admin_state_up}
-
- res = self.client.post(reverse(self.ADDMEMBER_PATH), form_data)
-
- self.assertFormErrors(res, 2)
-
- @test.create_stubs({api.lbaas: ('pools_get',),
- api.nova: ('server_list',)})
- def test_add_member_get(self):
- server1 = self.AttributeDict({'id':
- '12381d38-c3eb-4fee-9763-12de3338042e',
- 'name': 'vm1'})
- server2 = self.AttributeDict({'id':
- '12381d38-c3eb-4fee-9763-12de3338043e',
- 'name': 'vm2'})
-
- api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
- api.nova.server_list(
- IsA(http.HttpRequest)).AndReturn([[server1, server2], False])
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse(self.ADDMEMBER_PATH))
-
- workflow = res.context['workflow']
- self.assertTemplateUsed(res, WorkflowView.template_name)
- self.assertEqual(workflow.name, AddMember.name)
-
- expected_objs = ['<AddMemberStep: addmemberaction>', ]
- self.assertQuerysetEqual(workflow.steps, expected_objs)
-
- @test.create_stubs({api.lbaas: ('pool_get', 'pool_update')})
- def test_update_pool_post(self):
- pool = self.pools.first()
-
- api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).AndReturn(pool)
-
- data = {'name': pool.name,
- 'description': pool.description,
- 'lb_method': pool.lb_method,
- 'admin_state_up': pool.admin_state_up}
-
- api.lbaas.pool_update(IsA(http.HttpRequest), pool.id, pool=data)\
- .AndReturn(pool)
-
- self.mox.ReplayAll()
-
- form_data = data.copy()
- form_data.update({'pool_id': pool.id})
-
- res = self.client.post(
- reverse(self.UPDATEPOOL_PATH, args=(pool.id,)), form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
-
- @test.create_stubs({api.lbaas: ('pool_get',)})
- def test_update_pool_get(self):
- pool = self.pools.first()
-
- api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).AndReturn(pool)
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse(self.UPDATEPOOL_PATH, args=(pool.id,)))
-
- self.assertTemplateUsed(res, 'project/loadbalancers/updatepool.html')
-
- @test.create_stubs({api.lbaas: ('pools_get', 'vip_get',
- 'vip_update')})
- def test_update_vip_post(self):
- vip = self.vips.first()
-
- api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
- api.lbaas.vip_get(IsA(http.HttpRequest), vip.id).AndReturn(vip)
-
- data = {'name': vip.name,
- 'description': vip.description,
- 'pool_id': vip.pool_id,
- 'session_persistence': {},
- 'connection_limit': vip.connection_limit,
- 'admin_state_up': vip.admin_state_up}
-
- api.lbaas.vip_update(IsA(http.HttpRequest), vip.id, vip=data)\
- .AndReturn(vip)
-
- self.mox.ReplayAll()
-
- form_data = data.copy()
- form_data.update({'vip_id': vip.id})
-
- res = self.client.post(
- reverse(self.UPDATEVIP_PATH, args=(vip.id,)), form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
-
- @test.create_stubs({api.lbaas: ('vip_get', 'pools_get')})
- def test_update_vip_get(self):
- vip = self.vips.first()
-
- api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
- api.lbaas.vip_get(IsA(http.HttpRequest), vip.id).AndReturn(vip)
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse(self.UPDATEVIP_PATH, args=(vip.id,)))
-
- self.assertTemplateUsed(res, 'project/loadbalancers/updatevip.html')
-
- @test.create_stubs({api.lbaas: ('pools_get', 'member_get',
- 'member_update')})
- def test_update_member_post(self):
- member = self.members.first()
-
- api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
- api.lbaas.member_get(IsA(http.HttpRequest), member.id)\
- .AndReturn(member)
-
- data = {'pool_id': member.pool_id,
- 'weight': member.weight,
- 'admin_state_up': member.admin_state_up}
-
- api.lbaas.member_update(IsA(http.HttpRequest), member.id, member=data)\
- .AndReturn(member)
-
- self.mox.ReplayAll()
-
- form_data = data.copy()
- form_data.update({'member_id': member.id})
-
- res = self.client.post(
- reverse(self.UPDATEMEMBER_PATH, args=(member.id,)), form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
-
- @test.create_stubs({api.lbaas: ('member_get', 'pools_get')})
- def test_update_member_get(self):
- member = self.members.first()
-
- api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
- api.lbaas.member_get(IsA(http.HttpRequest), member.id)\
- .AndReturn(member)
-
- self.mox.ReplayAll()
-
- res = self.client.get(
- reverse(self.UPDATEMEMBER_PATH, args=(member.id,)))
-
- self.assertTemplateUsed(res, 'project/loadbalancers/updatemember.html')
-
- @test.create_stubs({api.lbaas: ('pool_health_monitor_get',
- 'pool_health_monitor_update')})
- def test_update_monitor_post(self):
- monitor = self.monitors.first()
-
- api.lbaas.pool_health_monitor_get(IsA(http.HttpRequest), monitor.id)\
- .AndReturn(monitor)
-
- data = {'delay': monitor.delay,
- 'timeout': monitor.timeout,
- 'max_retries': monitor.max_retries,
- 'admin_state_up': monitor.admin_state_up}
-
- api.lbaas.pool_health_monitor_update(IsA(http.HttpRequest),
- monitor.id, health_monitor=data).AndReturn(monitor)
-
- self.mox.ReplayAll()
-
- form_data = data.copy()
- form_data.update({'monitor_id': monitor.id})
-
- res = self.client.post(
- reverse(self.UPDATEMONITOR_PATH, args=(monitor.id,)), form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
-
- @test.create_stubs({api.lbaas: ('pool_health_monitor_get',)})
- def test_update_monitor_get(self):
- monitor = self.monitors.first()
-
- api.lbaas.pool_health_monitor_get(IsA(http.HttpRequest), monitor.id)\
- .AndReturn(monitor)
-
- self.mox.ReplayAll()
-
- res = self.client.get(
- reverse(self.UPDATEMONITOR_PATH, args=(monitor.id,)))
-
- self.assertTemplateUsed(
- res, 'project/loadbalancers/updatemonitor.html')
-
- @test.create_stubs({api.lbaas: ('pool_get', 'pool_health_monitors_get',
- 'pool_monitor_association_create')})
- def test_add_pool_monitor_association_post(self):
- pool = self.pools.first()
- monitors = self.monitors.list()
- monitor = self.monitors.list()[1]
-
- api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).AndReturn(pool)
- api.lbaas.pool_health_monitors_get(
- IsA(http.HttpRequest)).AndReturn(monitors)
-
- api.lbaas.pool_monitor_association_create(
- IsA(http.HttpRequest),
- monitor_id=monitor.id,
- pool_id=pool.id,
- pool_monitors=pool.health_monitors,
- pool_name=pool.name).AndReturn(None)
-
- self.mox.ReplayAll()
-
- form_data = {'monitor_id': monitor.id,
- 'pool_id': pool.id,
- 'pool_monitors': pool.health_monitors,
- 'pool_name': pool.name}
-
- res = self.client.post(
- reverse(self.ADDASSOC_PATH, args=(pool.id,)), form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
-
- @test.create_stubs({api.lbaas: ('pool_get', 'pool_health_monitors_get')})
- def test_add_pool_monitor_association_get(self):
- pool = self.pools.first()
- monitors = self.monitors.list()
-
- api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).AndReturn(pool)
- api.lbaas.pool_health_monitors_get(
- IsA(http.HttpRequest)).AndReturn(monitors)
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse(self.ADDASSOC_PATH, args=(pool.id,)))
-
- workflow = res.context['workflow']
- self.assertTemplateUsed(res, WorkflowView.template_name)
- self.assertEqual(workflow.name, AddPMAssociation.name)
-
- expected_objs = ['<AddPMAssociationStep: addpmassociationaction>', ]
- self.assertQuerysetEqual(workflow.steps, expected_objs)
-
- @test.create_stubs({api.lbaas: ('pool_get',
- 'pool_monitor_association_delete')})
- def test_delete_pool_monitor_association_post(self):
- pool = self.pools.first()
- monitor = self.monitors.first()
-
- api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).AndReturn(pool)
-
- api.lbaas.pool_monitor_association_delete(
- IsA(http.HttpRequest),
- monitor_id=monitor.id,
- pool_id=pool.id,
- pool_monitors=pool.health_monitors,
- pool_name=pool.name).AndReturn(None)
-
- self.mox.ReplayAll()
-
- form_data = {'monitor_id': monitor.id,
- 'pool_id': pool.id,
- 'pool_monitors': pool.health_monitors,
- 'pool_name': pool.name}
-
- res = self.client.post(
- reverse(self.DELETEASSOC_PATH, args=(pool.id,)), form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, str(self.INDEX_URL))
-
- @test.create_stubs({api.lbaas: ('pool_get',)})
- def test_delete_pool_monitor_association_get(self):
- pool = self.pools.first()
-
- api.lbaas.pool_get(IsA(http.HttpRequest), pool.id).AndReturn(pool)
-
- self.mox.ReplayAll()
-
- res = self.client.get(
- reverse(self.DELETEASSOC_PATH, args=(pool.id,)))
-
- workflow = res.context['workflow']
- self.assertTemplateUsed(res, WorkflowView.template_name)
- self.assertEqual(workflow.name, DeletePMAssociation.name)
-
- expected_objs = [
- '<DeletePMAssociationStep: deletepmassociationaction>', ]
- self.assertQuerysetEqual(workflow.steps, expected_objs)
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/urls.py b/openstack_dashboard/dashboards/project/loadbalancers/urls.py
deleted file mode 100644
index ab1cfba1..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/urls.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013, Big Switch Networks, 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- AddMemberView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- AddMonitorView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- AddPMAssociationView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- AddPoolView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- AddVipView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- DeletePMAssociationView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- IndexView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- MemberDetailsView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- MonitorDetailsView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- PoolDetailsView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- UpdateMemberView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- UpdateMonitorView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- UpdatePoolView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- UpdateVipView
-from openstack_dashboard.dashboards.project.loadbalancers.views import \
- VipDetailsView
-
-urlpatterns = patterns(
- 'openstack_dashboard.dashboards.project.loadbalancers.views',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^addpool$', AddPoolView.as_view(), name='addpool'),
- url(r'^updatepool/(?P<pool_id>[^/]+)/$',
- UpdatePoolView.as_view(), name='updatepool'),
- url(r'^addvip/(?P<pool_id>[^/]+)/$', AddVipView.as_view(), name='addvip'),
- url(r'^updatevip/(?P<vip_id>[^/]+)/$',
- UpdateVipView.as_view(), name='updatevip'),
- url(r'^addmember$', AddMemberView.as_view(), name='addmember'),
- url(r'^updatemember/(?P<member_id>[^/]+)/$',
- UpdateMemberView.as_view(), name='updatemember'),
- url(r'^addmonitor$', AddMonitorView.as_view(), name='addmonitor'),
- url(r'^updatemonitor/(?P<monitor_id>[^/]+)/$',
- UpdateMonitorView.as_view(), name='updatemonitor'),
- url(r'^association/add/(?P<pool_id>[^/]+)/$',
- AddPMAssociationView.as_view(), name='addassociation'),
- url(r'^association/delete/(?P<pool_id>[^/]+)/$',
- DeletePMAssociationView.as_view(), name='deleteassociation'),
- url(r'^pool/(?P<pool_id>[^/]+)/$',
- PoolDetailsView.as_view(), name='pooldetails'),
- url(r'^vip/(?P<vip_id>[^/]+)/$',
- VipDetailsView.as_view(), name='vipdetails'),
- url(r'^member/(?P<member_id>[^/]+)/$',
- MemberDetailsView.as_view(), name='memberdetails'),
- url(r'^monitor/(?P<monitor_id>[^/]+)/$',
- MonitorDetailsView.as_view(), name='monitordetails'))
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/views.py b/openstack_dashboard/dashboards/project/loadbalancers/views.py
deleted file mode 100644
index 580cbf51..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/views.py
+++ /dev/null
@@ -1,338 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013, Big Switch Networks, 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.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tabs
-from horizon import workflows
-
-import logging
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.loadbalancers.forms import \
- UpdateMember
-from openstack_dashboard.dashboards.project.loadbalancers.forms import \
- UpdateMonitor
-from openstack_dashboard.dashboards.project.loadbalancers.forms import \
- UpdatePool
-from openstack_dashboard.dashboards.project.loadbalancers.forms import \
- UpdateVip
-from openstack_dashboard.dashboards.project.loadbalancers.tabs import \
- LoadBalancerTabs
-from openstack_dashboard.dashboards.project.loadbalancers.tabs import \
- MemberDetailsTabs
-from openstack_dashboard.dashboards.project.loadbalancers.tabs import \
- MonitorDetailsTabs
-from openstack_dashboard.dashboards.project.loadbalancers.tabs import \
- PoolDetailsTabs
-from openstack_dashboard.dashboards.project.loadbalancers.tabs import \
- VipDetailsTabs
-from openstack_dashboard.dashboards.project.loadbalancers.workflows import \
- AddMember
-from openstack_dashboard.dashboards.project.loadbalancers.workflows import \
- AddMonitor
-from openstack_dashboard.dashboards.project.loadbalancers.workflows import \
- AddPMAssociation
-from openstack_dashboard.dashboards.project.loadbalancers.workflows import \
- AddPool
-from openstack_dashboard.dashboards.project.loadbalancers.workflows import \
- AddVip
-from openstack_dashboard.dashboards.project.loadbalancers.workflows import \
- DeletePMAssociation
-
-import re
-
-LOG = logging.getLogger(__name__)
-
-
-class IndexView(tabs.TabView):
- tab_group_class = (LoadBalancerTabs)
- template_name = 'project/loadbalancers/details_tabs.html'
-
- def post(self, request, *args, **kwargs):
- obj_ids = request.POST.getlist('object_ids')
- action = request.POST['action']
- m = re.search('.delete([a-z]+)', action).group(1)
- if obj_ids == []:
- obj_ids.append(re.search('([0-9a-z-]+)$', action).group(1))
- if m == 'monitor':
- for obj_id in obj_ids:
- try:
- api.lbaas.pool_health_monitor_delete(request, obj_id)
- except:
- exceptions.handle(request,
- _('Unable to delete monitor.'))
- if m == 'pool':
- for obj_id in obj_ids:
- try:
- api.lbaas.pool_delete(request, obj_id)
- except:
- exceptions.handle(request,
- _('Must delete VIP first.'))
- if m == 'member':
- for obj_id in obj_ids:
- try:
- api.lbaas.member_delete(request, obj_id)
- except:
- exceptions.handle(request,
- _('Unable to delete member.'))
- if m == 'vip':
- for obj_id in obj_ids:
- try:
- vip_id = api.lbaas.pool_get(request, obj_id).vip_id
- except:
- exceptions.handle(request,
- _('Unable to locate VIP to delete.'))
- if vip_id is not None:
- try:
- api.lbaas.vip_delete(request, vip_id)
- except:
- exceptions.handle(request,
- _('Unable to delete VIP.'))
- return self.get(request, *args, **kwargs)
-
-
-class AddPoolView(workflows.WorkflowView):
- workflow_class = AddPool
-
- def get_initial(self):
- initial = super(AddPoolView, self).get_initial()
- return initial
-
-
-class AddVipView(workflows.WorkflowView):
- workflow_class = AddVip
-
- def get_context_data(self, **kwargs):
- context = super(AddVipView, self).get_context_data(**kwargs)
- return context
-
- def get_initial(self):
- initial = super(AddVipView, self).get_initial()
- initial['pool_id'] = self.kwargs['pool_id']
- try:
- pool = api.lbaas.pool_get(self.request, initial['pool_id'])
- initial['subnet'] = api.neutron.subnet_get(
- self.request, pool.subnet_id).cidr
- except:
- initial['subnet'] = ''
- msg = _('Unable to retrieve pool subnet.')
- exceptions.handle(self.request, msg)
- return initial
-
-
-class AddMemberView(workflows.WorkflowView):
- workflow_class = AddMember
-
- def get_initial(self):
- initial = super(AddMemberView, self).get_initial()
- return initial
-
-
-class AddMonitorView(workflows.WorkflowView):
- workflow_class = AddMonitor
-
- def get_initial(self):
- initial = super(AddMonitorView, self).get_initial()
- return initial
-
-
-class PoolDetailsView(tabs.TabView):
- tab_group_class = (PoolDetailsTabs)
- template_name = 'project/loadbalancers/details_tabs.html'
-
-
-class VipDetailsView(tabs.TabView):
- tab_group_class = (VipDetailsTabs)
- template_name = 'project/loadbalancers/details_tabs.html'
-
-
-class MemberDetailsView(tabs.TabView):
- tab_group_class = (MemberDetailsTabs)
- template_name = 'project/loadbalancers/details_tabs.html'
-
-
-class MonitorDetailsView(tabs.TabView):
- tab_group_class = (MonitorDetailsTabs)
- template_name = 'project/loadbalancers/details_tabs.html'
-
-
-class UpdatePoolView(forms.ModalFormView):
- form_class = UpdatePool
- template_name = "project/loadbalancers/updatepool.html"
- context_object_name = 'pool'
- success_url = reverse_lazy("horizon:project:loadbalancers:index")
-
- def get_context_data(self, **kwargs):
- context = super(UpdatePoolView, self).get_context_data(**kwargs)
- context["pool_id"] = self.kwargs['pool_id']
- return context
-
- def _get_object(self, *args, **kwargs):
- if not hasattr(self, "_object"):
- pool_id = self.kwargs['pool_id']
- try:
- self._object = api.lbaas.pool_get(self.request, pool_id)
- except:
- redirect = self.success_url
- msg = _('Unable to retrieve pool details.')
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_initial(self):
- pool = self._get_object()
- return {'name': pool['name'],
- 'pool_id': pool['id'],
- 'description': pool['description'],
- 'lb_method': pool['lb_method'],
- 'admin_state_up': pool['admin_state_up']}
-
-
-class UpdateVipView(forms.ModalFormView):
- form_class = UpdateVip
- template_name = "project/loadbalancers/updatevip.html"
- context_object_name = 'vip'
- success_url = reverse_lazy("horizon:project:loadbalancers:index")
-
- def get_context_data(self, **kwargs):
- context = super(UpdateVipView, self).get_context_data(**kwargs)
- context["vip_id"] = self.kwargs['vip_id']
- return context
-
- def _get_object(self, *args, **kwargs):
- if not hasattr(self, "_object"):
- vip_id = self.kwargs['vip_id']
- try:
- self._object = api.lbaas.vip_get(self.request, vip_id)
- except:
- redirect = self.success_url
- msg = _('Unable to retrieve vip details.')
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_initial(self):
- vip = self._get_object()
- stype = vip['session_persistence']
- if stype['type'] == 'APP_COOKIE':
- cookie = stype['cookie_name']
- else:
- cookie = ''
-
- return {'name': vip['name'],
- 'vip_id': vip['id'],
- 'description': vip['description'],
- 'pool_id': vip['pool_id'],
- 'session_persistence': vip['session_persistence']['type'],
- 'cookie_name': cookie,
- 'connection_limit': vip['connection_limit'],
- 'admin_state_up': vip['admin_state_up']}
-
-
-class UpdateMemberView(forms.ModalFormView):
- form_class = UpdateMember
- template_name = "project/loadbalancers/updatemember.html"
- context_object_name = 'member'
- success_url = reverse_lazy("horizon:project:loadbalancers:index")
-
- def get_context_data(self, **kwargs):
- context = super(UpdateMemberView, self).get_context_data(**kwargs)
- context["member_id"] = self.kwargs['member_id']
- return context
-
- def _get_object(self, *args, **kwargs):
- if not hasattr(self, "_object"):
- member_id = self.kwargs['member_id']
- try:
- self._object = api.lbaas.member_get(self.request, member_id)
- except:
- redirect = self.success_url
- msg = _('Unable to retrieve member details.')
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_initial(self):
- member = self._get_object()
- return {'member_id': member['id'],
- 'pool_id': member['pool_id'],
- 'weight': member['weight'],
- 'admin_state_up': member['admin_state_up']}
-
-
-class UpdateMonitorView(forms.ModalFormView):
- form_class = UpdateMonitor
- template_name = "project/loadbalancers/updatemonitor.html"
- context_object_name = 'monitor'
- success_url = reverse_lazy("horizon:project:loadbalancers:index")
-
- def get_context_data(self, **kwargs):
- context = super(UpdateMonitorView, self).get_context_data(**kwargs)
- context["monitor_id"] = self.kwargs['monitor_id']
- return context
-
- def _get_object(self, *args, **kwargs):
- if not hasattr(self, "_object"):
- monitor_id = self.kwargs['monitor_id']
- try:
- self._object = api.lbaas.pool_health_monitor_get(
- self.request, monitor_id)
- except:
- redirect = self.success_url
- msg = _('Unable to retrieve health monitor details.')
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_initial(self):
- monitor = self._get_object()
- return {'monitor_id': monitor['id'],
- 'delay': monitor['delay'],
- 'timeout': monitor['timeout'],
- 'max_retries': monitor['max_retries'],
- 'admin_state_up': monitor['admin_state_up']}
-
-
-class AddPMAssociationView(workflows.WorkflowView):
- workflow_class = AddPMAssociation
-
- def get_initial(self):
- initial = super(AddPMAssociationView, self).get_initial()
- initial['pool_id'] = self.kwargs['pool_id']
- try:
- pool = api.lbaas.pool_get(self.request, initial['pool_id'])
- initial['pool_name'] = pool.name
- initial['pool_monitors'] = pool.health_monitors
- except:
- msg = _('Unable to retrieve pool.')
- exceptions.handle(self.request, msg)
- return initial
-
-
-class DeletePMAssociationView(workflows.WorkflowView):
- workflow_class = DeletePMAssociation
-
- def get_initial(self):
- initial = super(DeletePMAssociationView, self).get_initial()
- initial['pool_id'] = self.kwargs['pool_id']
- try:
- pool = api.lbaas.pool_get(self.request, initial['pool_id'])
- initial['pool_name'] = pool.name
- initial['pool_monitors'] = pool.health_monitors
- except:
- msg = _('Unable to retrieve pool.')
- exceptions.handle(self.request, msg)
- return initial
diff --git a/openstack_dashboard/dashboards/project/loadbalancers/workflows.py b/openstack_dashboard/dashboards/project/loadbalancers/workflows.py
deleted file mode 100644
index 69e7067b..00000000
--- a/openstack_dashboard/dashboards/project/loadbalancers/workflows.py
+++ /dev/null
@@ -1,609 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013, Big Switch Networks, 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 logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon.utils import fields
-from horizon.utils.validators import validate_port_range
-from horizon import workflows
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class AddPoolAction(workflows.Action):
- name = forms.CharField(max_length=80, label=_("Name"))
- description = forms.CharField(
- initial="", required=False,
- max_length=80, label=_("Description"))
- subnet_id = forms.ChoiceField(label=_("Subnet"))
- protocol = forms.ChoiceField(label=_("Protocol"))
- lb_method = forms.ChoiceField(label=_("Load Balancing Method"))
- admin_state_up = forms.BooleanField(label=_("Admin State"),
- initial=True, required=False)
-
- def __init__(self, request, *args, **kwargs):
- super(AddPoolAction, self).__init__(request, *args, **kwargs)
-
- tenant_id = request.user.tenant_id
-
- subnet_id_choices = [('', _("Select a Subnet"))]
- try:
- networks = api.neutron.network_list_for_tenant(request, tenant_id)
- except:
- exceptions.handle(request,
- _('Unable to retrieve networks list.'))
- networks = []
- for n in networks:
- for s in n['subnets']:
- subnet_id_choices.append((s.id, s.cidr))
- self.fields['subnet_id'].choices = subnet_id_choices
-
- protocol_choices = [('', _("Select a Protocol"))]
- protocol_choices.append(('HTTP', 'HTTP'))
- protocol_choices.append(('HTTPS', 'HTTPS'))
- self.fields['protocol'].choices = protocol_choices
-
- lb_method_choices = [('', _("Select a Method"))]
- lb_method_choices.append(('ROUND_ROBIN', 'ROUND_ROBIN'))
- lb_method_choices.append(('LEAST_CONNECTIONS', 'LEAST_CONNECTIONS'))
- lb_method_choices.append(('SOURCE_IP', 'SOURCE_IP'))
- self.fields['lb_method'].choices = lb_method_choices
-
- class Meta:
- name = _("Add New Pool")
- permissions = ('openstack.services.network',)
- help_text = _("Create Pool for current project.\n\n"
- "Assign a name and description for the pool. "
- "Choose one subnet where all members of this "
- "pool must be on. "
- "Select the protocol and load balancing method "
- "for this pool. "
- "Admin State is UP (checked) by default.")
-
-
-class AddPoolStep(workflows.Step):
- action_class = AddPoolAction
- contributes = ("name", "description", "subnet_id",
- "protocol", "lb_method", "admin_state_up")
-
- def contribute(self, data, context):
- context = super(AddPoolStep, self).contribute(data, context)
- if data:
- return context
-
-
-class AddPool(workflows.Workflow):
- slug = "addpool"
- name = _("Add Pool")
- finalize_button_name = _("Add")
- success_message = _('Added pool "%s".')
- failure_message = _('Unable to add pool "%s".')
- success_url = "horizon:project:loadbalancers:index"
- default_steps = (AddPoolStep,)
-
- def format_status_message(self, message):
- name = self.context.get('name')
- return message % name
-
- def handle(self, request, context):
- try:
- api.lbaas.pool_create(request, **context)
- return True
- except:
- return False
-
-
-class AddVipAction(workflows.Action):
- name = forms.CharField(max_length=80, label=_("Name"))
- description = forms.CharField(
- initial="", required=False,
- max_length=80, label=_("Description"))
- floatip_address = forms.ChoiceField(
- label=_("VIP Address from Floating IPs"),
- widget=forms.Select(attrs={'disabled': 'disabled'}),
- required=False)
- other_address = fields.IPField(required=False,
- initial="",
- version=fields.IPv4,
- mask=False)
- protocol_port = forms.IntegerField(label=_("Protocol Port"), min_value=1,
- help_text=_("Enter an integer value "
- "between 1 and 65535."),
- validators=[validate_port_range])
- protocol = forms.ChoiceField(label=_("Protocol"))
- session_persistence = forms.ChoiceField(
- required=False, initial={}, label=_("Session Persistence"))
- cookie_name = forms.CharField(
- initial="", required=False,
- max_length=80, label=_("Cookie Name"),
- help_text=_("Required for APP_COOKIE persistence;"
- " Ignored otherwise."))
- connection_limit = forms.IntegerField(
- min_value=-1, label=_("Connection Limit"),
- help_text=_("Maximum number of connections allowed "
- "for the VIP or '-1' if the limit is not set"))
- admin_state_up = forms.BooleanField(
- label=_("Admin State"), initial=True, required=False)
-
- def __init__(self, request, *args, **kwargs):
- super(AddVipAction, self).__init__(request, *args, **kwargs)
-
- self.fields['other_address'].label = _("Specify a free IP address"
- " from %s" %
- args[0]['subnet'])
-
- protocol_choices = [('', _("Select a Protocol"))]
- protocol_choices.append(('HTTP', 'HTTP'))
- protocol_choices.append(('HTTPS', 'HTTPS'))
- self.fields['protocol'].choices = protocol_choices
-
- session_persistence_choices = [('', _("Set Session Persistence"))]
- for mode in ('SOURCE_IP', 'HTTP_COOKIE', 'APP_COOKIE'):
- session_persistence_choices.append((mode, mode))
- self.fields[
- 'session_persistence'].choices = session_persistence_choices
-
- floatip_address_choices = [('', _("Currently Not Supported"))]
- self.fields['floatip_address'].choices = floatip_address_choices
-
- def clean(self):
- cleaned_data = super(AddVipAction, self).clean()
- if (cleaned_data.get('session_persistence') == 'APP_COOKIE' and
- not cleaned_data.get('cookie_name')):
- msg = _('Cookie name is required for APP_COOKIE persistence.')
- self._errors['cookie_name'] = self.error_class([msg])
- return cleaned_data
-
- class Meta:
- name = _("Specify VIP")
- permissions = ('openstack.services.network',)
- help_text = _("Create a VIP for this pool. "
- "Assign a name and description for the VIP. "
- "Specify an IP address and port for the VIP. "
- "Choose the protocol and session persistence "
- "method for the VIP."
- "Specify the max connections allowed. "
- "Admin State is UP (checked) by default.")
-
-
-class AddVipStep(workflows.Step):
- action_class = AddVipAction
- depends_on = ("pool_id", "subnet")
- contributes = ("name", "description", "floatip_address",
- "other_address", "protocol_port", "protocol",
- "session_persistence", "cookie_name",
- "connection_limit", "admin_state_up")
-
- def contribute(self, data, context):
- context = super(AddVipStep, self).contribute(data, context)
- return context
-
-
-class AddVip(workflows.Workflow):
- slug = "addvip"
- name = _("Add VIP")
- finalize_button_name = _("Add")
- success_message = _('Added VIP "%s".')
- failure_message = _('Unable to add VIP "%s".')
- success_url = "horizon:project:loadbalancers:index"
- default_steps = (AddVipStep,)
-
- def format_status_message(self, message):
- name = self.context.get('name')
- return message % name
-
- def handle(self, request, context):
- if context['other_address'] == '':
- context['address'] = context['floatip_address']
- else:
- if not context['floatip_address'] == '':
- self.failure_message = _('Only one address can be specified. '
- 'Unable to add VIP "%s".')
- return False
- else:
- context['address'] = context['other_address']
- try:
- pool = api.lbaas.pool_get(request, context['pool_id'])
- context['subnet_id'] = pool['subnet_id']
- except:
- context['subnet_id'] = None
- self.failure_message = _('Unable to retrieve the specified pool. '
- 'Unable to add VIP "%s".')
- return False
-
- if context['session_persistence']:
- stype = context['session_persistence']
- if stype == 'APP_COOKIE':
- cookie = context['cookie_name']
- context['session_persistence'] = {'type': stype,
- 'cookie_name': cookie}
- else:
- context['session_persistence'] = {'type': stype}
- else:
- context['session_persistence'] = {}
-
- try:
- api.lbaas.vip_create(request, **context)
- return True
- except:
- return False
-
-
-class AddMemberAction(workflows.Action):
- pool_id = forms.ChoiceField(label=_("Pool"))
- members = forms.MultipleChoiceField(
- label=_("Member(s)"),
- required=True,
- initial=["default"],
- widget=forms.CheckboxSelectMultiple(),
- error_messages={'required':
- _('At least one member must be specified')},
- help_text=_("Select members for this pool "))
- weight = forms.IntegerField(max_value=256, min_value=0, label=_("Weight"),
- help_text=_("Relative part of requests this "
- "pool member serves compared to others"))
- protocol_port = forms.IntegerField(label=_("Protocol Port"), min_value=1,
- help_text=_("Enter an integer value "
- "between 1 and 65535."),
- validators=[validate_port_range])
- admin_state_up = forms.BooleanField(label=_("Admin State"),
- initial=True, required=False)
-
- def __init__(self, request, *args, **kwargs):
- super(AddMemberAction, self).__init__(request, *args, **kwargs)
-
- pool_id_choices = [('', _("Select a Pool"))]
- try:
- pools = api.lbaas.pools_get(request)
- except:
- pools = []
- exceptions.handle(request,
- _('Unable to retrieve pools list.'))
- pools = sorted(pools,
- key=lambda pool: pool.name)
- for p in pools:
- pool_id_choices.append((p.id, p.name))
- self.fields['pool_id'].choices = pool_id_choices
-
- members_choices = []
- try:
- servers, has_more = api.nova.server_list(request)
- except:
- servers = []
- exceptions.handle(request,
- _('Unable to retrieve instances list.'))
-
- if len(servers) == 0:
- self.fields['members'].label = _("No servers available. "
- "Click Add to cancel.")
- self.fields['members'].required = False
- self.fields['members'].help_text = _("Select members "
- "for this pool ")
- self.fields['pool_id'].required = False
- self.fields['weight'].required = False
- self.fields['protocol_port'].required = False
- return
-
- for m in servers:
- members_choices.append((m.id, m.name))
- self.fields['members'].choices = sorted(
- members_choices,
- key=lambda member: member[1])
-
- class Meta:
- name = _("Add New Member")
- permissions = ('openstack.services.network',)
- help_text = _("Add member to selected pool.\n\n"
- "Choose one or more listed instances to be "
- "added to the pool as member(s). "
- "Assign a numeric weight for this member "
- "Specify the port number the member(s) "
- "operate on; e.g., 80.")
-
-
-class AddMemberStep(workflows.Step):
- action_class = AddMemberAction
- contributes = ("pool_id", "members", "protocol_port", "weight",
- "admin_state_up")
-
- def contribute(self, data, context):
- context = super(AddMemberStep, self).contribute(data, context)
- return context
-
-
-class AddMember(workflows.Workflow):
- slug = "addmember"
- name = _("Add Member")
- finalize_button_name = _("Add")
- success_message = _('Added member(s).')
- failure_message = _('Unable to add member(s).')
- success_url = "horizon:project:loadbalancers:index"
- default_steps = (AddMemberStep,)
-
- def handle(self, request, context):
- for m in context['members']:
- params = {'device_id': m}
- try:
- plist = api.neutron.port_list(request, **params)
- except:
- return False
- if plist:
- context['address'] = plist[0].fixed_ips[0]['ip_address']
- try:
- context['member_id'] = api.lbaas.member_create(
- request, **context).id
- except:
- return False
- return True
-
-
-class AddMonitorAction(workflows.Action):
- type = forms.ChoiceField(
- label=_("Type"),
- choices=[('ping', _('PING')),
- ('tcp', _('TCP')),
- ('http', _('HTTP')),
- ('https', _('HTTPS'))],
- widget=forms.Select(attrs={
- 'class': 'switchable',
- 'data-slug': 'type'
- }))
- delay = forms.IntegerField(
- min_value=1,
- label=_("Delay"),
- help_text=_("The minimum time in seconds between regular checks "
- "of a member"))
- timeout = forms.IntegerField(
- min_value=1,
- label=_("Timeout"),
- help_text=_("The maximum time in seconds for a monitor to wait "
- "for a reply"))
- max_retries = forms.IntegerField(
- max_value=10, min_value=1,
- label=_("Max Retries (1~10)"),
- help_text=_("Number of permissible failures before changing "
- "the status of member to inactive"))
- http_method = forms.ChoiceField(
- initial="GET",
- required=False,
- choices=[('GET', _('GET'))],
- label=_("HTTP Method"),
- help_text=_("HTTP method used to check health status of a member"),
- widget=forms.Select(attrs={
- 'class': 'switched',
- 'data-switch-on': 'type',
- 'data-type-http': _('HTTP Method'),
- 'data-type-https': _('HTTP Method')
- }))
- url_path = forms.CharField(
- initial="/",
- required=False,
- max_length=80,
- label=_("URL"),
- widget=forms.TextInput(attrs={
- 'class': 'switched',
- 'data-switch-on': 'type',
- 'data-type-http': _('URL'),
- 'data-type-https': _('URL')
- }))
- expected_codes = forms.RegexField(
- initial="200",
- required=False,
- max_length=80,
- regex=r'^(\d{3}(\s*,\s*\d{3})*)$|^(\d{3}-\d{3})$',
- label=_("Expected HTTP Status Codes"),
- help_text=_("Expected code may be a single value (e.g. 200), "
- "a list of values (e.g. 200, 202), "
- "or range of values (e.g. 200-204)"),
- widget=forms.TextInput(attrs={
- 'class': 'switched',
- 'data-switch-on': 'type',
- 'data-type-http': _('Expected HTTP Status Codes'),
- 'data-type-https': _('Expected HTTP Status Codes')
- }))
- admin_state_up = forms.BooleanField(label=_("Admin State"),
- initial=True, required=False)
-
- def __init__(self, request, *args, **kwargs):
- super(AddMonitorAction, self).__init__(request, *args, **kwargs)
-
- def clean(self):
- cleaned_data = super(AddMonitorAction, self).clean()
- type_opt = cleaned_data.get('type')
-
- if type_opt in ['http', 'https']:
- http_method_opt = cleaned_data.get('http_method')
- url_path = cleaned_data.get('url_path')
- expected_codes = cleaned_data.get('expected_codes')
-
- if not http_method_opt:
- msg = _('Please choose a HTTP method')
- self._errors['http_method'] = self.error_class([msg])
- if not url_path:
- msg = _('Please specify an URL')
- self._errors['url_path'] = self.error_class([msg])
- if not expected_codes:
- msg = _('Please enter a single value (e.g. 200), '
- 'a list of values (e.g. 200, 202), '
- 'or range of values (e.g. 200-204)')
- self._errors['expected_codes'] = self.error_class([msg])
- return cleaned_data
-
- class Meta:
- name = _("Add New Monitor")
- permissions = ('openstack.services.network',)
- help_text = _("Create a monitor template.\n\n"
- "Select type of monitoring. "
- "Specify delay, timeout, and retry limits "
- "required by the monitor. "
- "Specify method, URL path, and expected "
- "HTTP codes upon success.")
-
-
-class AddMonitorStep(workflows.Step):
- action_class = AddMonitorAction
- contributes = ("type", "delay", "timeout", "max_retries",
- "http_method", "url_path", "expected_codes",
- "admin_state_up")
-
- def contribute(self, data, context):
- context = super(AddMonitorStep, self).contribute(data, context)
- if data:
- return context
-
-
-class AddMonitor(workflows.Workflow):
- slug = "addmonitor"
- name = _("Add Monitor")
- finalize_button_name = _("Add")
- success_message = _('Added monitor')
- failure_message = _('Unable to add monitor')
- success_url = "horizon:project:loadbalancers:index"
- default_steps = (AddMonitorStep,)
-
- def handle(self, request, context):
- try:
- context['monitor_id'] = api.lbaas.pool_health_monitor_create(
- request, **context).get('id')
- return True
- except:
- exceptions.handle(request, _("Unable to add monitor."))
- return False
-
-
-class AddPMAssociationAction(workflows.Action):
- monitor_id = forms.ChoiceField(label=_("Monitor"))
-
- def __init__(self, request, *args, **kwargs):
- super(AddPMAssociationAction, self).__init__(request, *args, **kwargs)
-
- def populate_monitor_id_choices(self, request, context):
- self.fields['monitor_id'].label = _("Select a monitor template "
- "for %s" % context['pool_name'])
-
- monitor_id_choices = [('', _("Select a Monitor"))]
- try:
- monitors = api.lbaas.pool_health_monitors_get(request)
- for m in monitors:
- if m.id not in context['pool_monitors']:
- monitor_id_choices.append((m.id, m.id))
- except:
- exceptions.handle(request,
- _('Unable to retrieve monitors list.'))
- self.fields['monitor_id'].choices = monitor_id_choices
-
- return monitor_id_choices
-
- class Meta:
- name = _("Association Details")
- permissions = ('openstack.services.network',)
- help_text = _("Associate a health monitor with target pool.")
-
-
-class AddPMAssociationStep(workflows.Step):
- action_class = AddPMAssociationAction
- depends_on = ("pool_id", "pool_name", "pool_monitors")
- contributes = ("monitor_id",)
-
- def contribute(self, data, context):
- context = super(AddPMAssociationStep, self).contribute(data, context)
- if data:
- return context
-
-
-class AddPMAssociation(workflows.Workflow):
- slug = "addassociation"
- name = _("Add Association")
- finalize_button_name = _("Add")
- success_message = _('Added association.')
- failure_message = _('Unable to add association.')
- success_url = "horizon:project:loadbalancers:index"
- default_steps = (AddPMAssociationStep,)
-
- def handle(self, request, context):
- try:
- context['monitor_id'] = api.lbaas.pool_monitor_association_create(
- request, **context)
- return True
- except:
- exceptions.handle(request, _("Unable to add association."))
- return False
-
-
-class DeletePMAssociationAction(workflows.Action):
- monitor_id = forms.ChoiceField(label=_("Monitor"))
-
- def __init__(self, request, *args, **kwargs):
- super(DeletePMAssociationAction, self).__init__(
- request, *args, **kwargs)
-
- def populate_monitor_id_choices(self, request, context):
- self.fields['monitor_id'].label = _("Select a health monitor of %s" %
- context['pool_name'])
-
- monitor_id_choices = [('', _("Select a Monitor"))]
- try:
- for m_id in context['pool_monitors']:
- monitor_id_choices.append((m_id, m_id))
- except:
- exceptions.handle(request,
- _('Unable to retrieve monitors list.'))
- self.fields['monitor_id'].choices = monitor_id_choices
-
- return monitor_id_choices
-
- class Meta:
- name = _("Association Details")
- permissions = ('openstack.services.network',)
- help_text = _("Disassociate a health monitor from target pool. ")
-
-
-class DeletePMAssociationStep(workflows.Step):
- action_class = DeletePMAssociationAction
- depends_on = ("pool_id", "pool_name", "pool_monitors")
- contributes = ("monitor_id",)
-
- def contribute(self, data, context):
- context = super(DeletePMAssociationStep, self).contribute(
- data, context)
- if data:
- return context
-
-
-class DeletePMAssociation(workflows.Workflow):
- slug = "deleteassociation"
- name = _("Delete Association")
- finalize_button_name = _("Delete")
- success_message = _('Deleted association.')
- failure_message = _('Unable to delete association.')
- success_url = "horizon:project:loadbalancers:index"
- default_steps = (DeletePMAssociationStep,)
-
- def handle(self, request, context):
- try:
- context['monitor_id'] = api.lbaas.pool_monitor_association_delete(
- request, **context)
- return True
- except:
- exceptions.handle(request, _("Unable to delete association."))
- return False
diff --git a/openstack_dashboard/dashboards/project/models.py b/openstack_dashboard/dashboards/project/models.py
deleted file mode 100644
index 6313a32f..00000000
--- a/openstack_dashboard/dashboards/project/models.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/openstack_dashboard/dashboards/project/network_topology/__init__.py b/openstack_dashboard/dashboards/project/network_topology/__init__.py
deleted file mode 100644
index 3b67d105..00000000
--- a/openstack_dashboard/dashboards/project/network_topology/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2013 NTT MCL, 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.
diff --git a/openstack_dashboard/dashboards/project/network_topology/panel.py b/openstack_dashboard/dashboards/project/network_topology/panel.py
deleted file mode 100644
index 4277da73..00000000
--- a/openstack_dashboard/dashboards/project/network_topology/panel.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2013 NTT MCL, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.project import dashboard
-
-
-class NetworkTopology(horizon.Panel):
- name = _("Network Topology")
- slug = 'network_topology'
- permissions = ('openstack.services.network', )
-
-
-dashboard.Project.register(NetworkTopology)
diff --git a/openstack_dashboard/dashboards/project/network_topology/templates/network_topology/index.html b/openstack_dashboard/dashboards/project/network_topology/templates/network_topology/index.html
deleted file mode 100644
index 75868d75..00000000
--- a/openstack_dashboard/dashboards/project/network_topology/templates/network_topology/index.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% load url from future %}
-{% block title %}{% trans "Network Topology" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Network Topology") %}
-{% endblock page_header %}
-
-{% block main %}
-<style>
-/* TODO(nati): The following styles are not work with compress, so put it here tempolary */
-div.network .router:hover div.port,
-div.network .server:hover div.port,
-div.network .device:hover div.port {
- background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(0, 0, 0, 0.25)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(0, 0, 0, 0.25)), color-stop(0.75, rgba(0, 0, 0, 0.25)), color-stop(0.75, transparent), to(transparent));
- background-image: -webkit-linear-gradient(-45deg, rgba(0, 0, 0, 0.25) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.25) 50%, rgba(0, 0, 0, 0.25) 75%, transparent 75%, transparent);
- background-image: -moz-linear-gradient(-45deg, rgba(0, 0, 0, 0.25) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.25) 50%, rgba(0, 0, 0, 0.25) 75%, transparent 75%, transparent);
- background-image: -o-linear-gradient(-45deg, rgba(0, 0, 0, 0.25) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.25) 50%, rgba(0, 0, 0, 0.25) 75%, transparent 75%, transparent);
- background-image: linear-gradient(-45deg, rgba(0, 0, 0, 0.25) 25%, transparent 25%, transparent 50%, rgba(0, 0, 0, 0.25) 50%, rgba(0, 0, 0, 0.25) 75%, transparent 75%, transparent);
-}
-</style>
-<noscript>
-{% trans "This pane needs javascript support." %}
-</noscript>
-<div class="launchButtons">
-<a href="{% url 'horizon:project:instances:launch' %}" id="instances__action_launch" class="btn btn-small btn-launch ajax-modal">{%trans "Launch Instance" %}</a>
-<a href="{% url 'horizon:project:networks:create' %}" id="networks__action_create" class="btn btn-small ajax-modal btn-create">{%trans "Create Network" %}</a>
-<a href="{% url 'horizon:project:routers:create' %}" id="Routers__action_create" class="btn btn-small ajax-modal btn-create">{%trans "Create Router" %}</a>
-</div>
-
-<div id="topologyCanvas">
- <div class="networks"></div>
- <div class="nodata">{% blocktrans %}There are no networks, routers, or connected instances to display. {% endblocktrans %}</div>
-</div>
-<span data-networktopology="{% url 'horizon:project:network_topology:json' %}" id="networktopology"></span>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/network_topology/urls.py b/openstack_dashboard/dashboards/project/network_topology/urls.py
deleted file mode 100644
index 8b3f8fe8..00000000
--- a/openstack_dashboard/dashboards/project/network_topology/urls.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2013 NTT MCL, 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.network_topology.views \
- import JSONView
-from openstack_dashboard.dashboards.project.network_topology.views \
- import NetworkTopology
-
-
-urlpatterns = patterns(
- 'openstack_dashboard.dashboards.project.network_topology.views',
- url(r'^$', NetworkTopology.as_view(), name='index'),
- url(r'^json$', JSONView.as_view(), name='json'),
-)
diff --git a/openstack_dashboard/dashboards/project/network_topology/views.py b/openstack_dashboard/dashboards/project/network_topology/views.py
deleted file mode 100644
index fd621c0a..00000000
--- a/openstack_dashboard/dashboards/project/network_topology/views.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2013 NTT MCL 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 json
-
-from django.core.urlresolvers import reverse
-from django.http import HttpResponse
-from django.views.generic import TemplateView
-from django.views.generic import View
-
-from openstack_dashboard import api
-
-
-class NetworkTopology(TemplateView):
- template_name = 'project/network_topology/index.html'
-
-
-class JSONView(View):
- def add_resource_url(self, view, resources):
- tenant_id = self.request.user.tenant_id
- for resource in resources:
- if (resource.get('tenant_id')
- and tenant_id != resource.get('tenant_id')):
- continue
- resource['url'] = reverse(view, None, [str(resource['id'])])
-
- def _check_router_external_port(self, ports, router_id, network_id):
- for port in ports:
- if (port['network_id'] == network_id
- and port['device_id'] == router_id):
- return True
- return False
-
- def get(self, request, *args, **kwargs):
- data = {}
- # Get nova data
- try:
- servers, more = api.nova.server_list(request)
- except:
- servers = []
- data['servers'] = [{'name': server.name,
- 'status': server.status,
- 'id': server.id} for server in servers]
- self.add_resource_url('horizon:project:instances:detail',
- data['servers'])
-
- # Get neutron data
- try:
- neutron_public_networks = api.neutron.network_list(request,
- **{'router:external': True})
- neutron_networks = api.neutron.network_list_for_tenant(request,
- request.user.tenant_id)
- neutron_subnets = api.neutron.subnet_list(request,
- tenant_id=request.user.tenant_id)
- neutron_ports = api.neutron.port_list(request,
- tenant_id=request.user.tenant_id)
- neutron_routers = api.neutron.router_list(request,
- tenant_id=request.user.tenant_id)
- except:
- neutron_public_networks = []
- neutron_networks = []
- neutron_subnets = []
- neutron_ports = []
- neutron_routers = []
-
- networks = [{'name': network.name,
- 'id': network.id,
- 'router:external': network['router:external']}
- for network in neutron_networks]
- self.add_resource_url('horizon:project:networks:detail',
- networks)
- # Add public networks to the networks list
- for publicnet in neutron_public_networks:
- found = False
- for network in networks:
- if publicnet.id == network['id']:
- found = True
- if not found:
- networks.append({'name': publicnet.name,
- 'id': publicnet.id,
- 'router:external': publicnet['router:external']})
- data['networks'] = sorted(networks,
- key=lambda x: x.get('router:external'),
- reverse=True)
-
- data['subnets'] = [{'id': subnet.id,
- 'cidr': subnet.cidr,
- 'network_id': subnet.network_id}
- for subnet in neutron_subnets]
-
- data['ports'] = [{'id': port.id,
- 'network_id': port.network_id,
- 'device_id': port.device_id,
- 'fixed_ips': port.fixed_ips} for port in neutron_ports]
- self.add_resource_url('horizon:project:networks:ports:detail',
- data['ports'])
-
- data['routers'] = [{'id': router.id,
- 'name': router.name,
- 'external_gateway_info': router.external_gateway_info}
- for router in neutron_routers]
-
- # user can't see port on external network. so we are
- # adding fake port based on router information
- for router in data['routers']:
- external_gateway_info = router.get('external_gateway_info')
- if not external_gateway_info:
- continue
- external_network = external_gateway_info.get(
- 'network_id')
- if not external_network:
- continue
- if self._check_router_external_port(data['ports'],
- router['id'],
- external_network):
- continue
- fake_port = {'id': 'fake%s' % external_network,
- 'network_id': external_network,
- 'device_id': router['id'],
- 'fixed_ips': []}
- data['ports'].append(fake_port)
-
- self.add_resource_url('horizon:project:routers:detail',
- data['routers'])
- json_string = json.dumps(data, ensure_ascii=False)
- return HttpResponse(json_string, mimetype='text/json')
diff --git a/openstack_dashboard/dashboards/project/networks/__init__.py b/openstack_dashboard/dashboards/project/networks/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/networks/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/networks/forms.py b/openstack_dashboard/dashboards/project/networks/forms.py
deleted file mode 100644
index 9f30482b..00000000
--- a/openstack_dashboard/dashboards/project/networks/forms.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class UpdateNetwork(forms.SelfHandlingForm):
- name = forms.CharField(label=_("Name"), required=False)
- tenant_id = forms.CharField(widget=forms.HiddenInput)
- network_id = forms.CharField(label=_("ID"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- admin_state = forms.BooleanField(label=_("Admin State"), required=False)
- failure_url = 'horizon:project:networks:index'
-
- def handle(self, request, data):
- try:
- params = {'admin_state_up': data['admin_state'],
- 'name': data['name']}
- network = api.neutron.network_modify(request, data['network_id'],
- **params)
- msg = _('Network %s was successfully updated.') % data['name']
- LOG.debug(msg)
- messages.success(request, msg)
- return network
- except:
- msg = _('Failed to update network %s') % data['name']
- LOG.info(msg)
- redirect = reverse(self.failure_url)
- exceptions.handle(request, msg, redirect=redirect)
diff --git a/openstack_dashboard/dashboards/project/networks/panel.py b/openstack_dashboard/dashboards/project/networks/panel.py
deleted file mode 100644
index 96b472ef..00000000
--- a/openstack_dashboard/dashboards/project/networks/panel.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.dashboards.project import dashboard
-
-
-class Networks(horizon.Panel):
- name = _("Networks")
- slug = 'networks'
- permissions = ('openstack.services.network',)
-
-dashboard.Project.register(Networks)
diff --git a/openstack_dashboard/dashboards/project/networks/ports/__init__.py b/openstack_dashboard/dashboards/project/networks/ports/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/networks/ports/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/networks/ports/forms.py b/openstack_dashboard/dashboards/project/networks/ports/forms.py
deleted file mode 100644
index fa20870a..00000000
--- a/openstack_dashboard/dashboards/project/networks/ports/forms.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class UpdatePort(forms.SelfHandlingForm):
- network_id = forms.CharField(widget=forms.HiddenInput())
- port_id = forms.CharField(widget=forms.HiddenInput())
- name = forms.CharField(max_length=255,
- label=_("Name"),
- required=False)
- admin_state = forms.BooleanField(label=_("Admin State"), required=False)
- failure_url = 'horizon:project:networks:detail'
-
- def handle(self, request, data):
- try:
- LOG.debug('params = %s' % data)
- port = api.neutron.port_modify(request, data['port_id'],
- name=data['name'],
- admin_state_up=data['admin_state'])
- msg = _('Port %s was successfully updated.') % data['port_id']
- LOG.debug(msg)
- messages.success(request, msg)
- return port
- except Exception:
- msg = _('Failed to update port %s') % data['port_id']
- LOG.info(msg)
- redirect = reverse(self.failure_url,
- args=[data['network_id']])
- exceptions.handle(request, msg, redirect=redirect)
diff --git a/openstack_dashboard/dashboards/project/networks/ports/tables.py b/openstack_dashboard/dashboards/project/networks/ports/tables.py
deleted file mode 100644
index 0397bbd4..00000000
--- a/openstack_dashboard/dashboards/project/networks/ports/tables.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django import template
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-
-
-LOG = logging.getLogger(__name__)
-
-
-def get_fixed_ips(port):
- template_name = 'project/networks/ports/_port_ips.html'
- context = {"ips": port.fixed_ips}
- return template.loader.render_to_string(template_name, context)
-
-
-def get_attached(port):
- if port['device_owner']:
- return port['device_owner']
- elif port['device_id']:
- return _('Attached')
- else:
- return _('Detached')
-
-
-class UpdatePort(tables.LinkAction):
- name = "update"
- verbose_name = _("Edit Port")
- url = "horizon:project:networks:editport"
- classes = ("ajax-modal", "btn-edit")
-
- def get_link_url(self, port):
- network_id = self.table.kwargs['network_id']
- return reverse(self.url, args=(network_id, port.id))
-
-
-class PortsTable(tables.DataTable):
- name = tables.Column("name",
- verbose_name=_("Name"),
- link="horizon:project:networks:ports:detail")
- fixed_ips = tables.Column(get_fixed_ips, verbose_name=_("Fixed IPs"))
- attached = tables.Column(get_attached, verbose_name=_("Attached Device"))
- status = tables.Column("status", verbose_name=_("Status"))
- admin_state = tables.Column("admin_state",
- verbose_name=_("Admin State"))
-
- def get_object_display(self, port):
- return port.id
-
- class Meta:
- name = "ports"
- verbose_name = _("Ports")
- row_actions = (UpdatePort,)
diff --git a/openstack_dashboard/dashboards/project/networks/ports/tabs.py b/openstack_dashboard/dashboards/project/networks/ports/tabs.py
deleted file mode 100644
index 77a356ba..00000000
--- a/openstack_dashboard/dashboards/project/networks/ports/tabs.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "overview"
- template_name = "project/networks/ports/_detail_overview.html"
-
- def get_context_data(self, request):
- port_id = self.tab_group.kwargs['port_id']
- try:
- port = api.neutron.port_get(self.request, port_id)
- except:
- redirect = reverse('horizon:project:networks:index')
- msg = _('Unable to retrieve port details.')
- exceptions.handle(request, msg, redirect=redirect)
- return {'port': port}
-
-
-class PortDetailTabs(tabs.TabGroup):
- slug = "port_details"
- tabs = (OverviewTab,)
diff --git a/openstack_dashboard/dashboards/project/networks/ports/urls.py b/openstack_dashboard/dashboards/project/networks/ports/urls.py
deleted file mode 100644
index be839b52..00000000
--- a/openstack_dashboard/dashboards/project/networks/ports/urls.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.networks.ports.views \
- import DetailView
-
-
-PORTS = r'^(?P<port_id>[^/]+)/%s$'
-VIEW_MOD = 'openstack_dashboard.dashboards.project.networks.ports.views'
-
-
-urlpatterns = patterns(VIEW_MOD,
- url(PORTS % 'detail', DetailView.as_view(), name='detail')
-)
diff --git a/openstack_dashboard/dashboards/project/networks/ports/views.py b/openstack_dashboard/dashboards/project/networks/ports/views.py
deleted file mode 100644
index 1a4f395f..00000000
--- a/openstack_dashboard/dashboards/project/networks/ports/views.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tabs
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.project.networks.ports.forms \
- import UpdatePort
-from openstack_dashboard.dashboards.project.networks.ports.tabs \
- import PortDetailTabs
-
-
-class DetailView(tabs.TabView):
- tab_group_class = PortDetailTabs
- template_name = 'project/networks/ports/detail.html'
-
-
-class UpdateView(forms.ModalFormView):
- form_class = UpdatePort
- template_name = 'project/networks/ports/update.html'
- context_object_name = 'port'
- success_url = 'horizon:project:networks:detail'
-
- def get_success_url(self):
- return reverse(self.success_url,
- args=(self.kwargs['network_id'],))
-
- def _get_object(self, *args, **kwargs):
- if not hasattr(self, "_object"):
- port_id = self.kwargs['port_id']
- try:
- self._object = api.neutron.port_get(self.request, port_id)
- except:
- redirect = reverse("horizon:project:networks:detail",
- args=(self.kwargs['network_id'],))
- msg = _('Unable to retrieve port details')
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_context_data(self, **kwargs):
- context = super(UpdateView, self).get_context_data(**kwargs)
- port = self._get_object()
- context['port_id'] = port['id']
- context['network_id'] = port['network_id']
- return context
-
- def get_initial(self):
- port = self._get_object()
- return {'port_id': port['id'],
- 'network_id': port['network_id'],
- 'tenant_id': port['tenant_id'],
- 'name': port['name'],
- 'admin_state': port['admin_state_up'],
- 'device_id': port['device_id'],
- 'device_owner': port['device_owner']}
diff --git a/openstack_dashboard/dashboards/project/networks/subnets/__init__.py b/openstack_dashboard/dashboards/project/networks/subnets/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/networks/subnets/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/networks/subnets/tables.py b/openstack_dashboard/dashboards/project/networks/subnets/tables.py
deleted file mode 100644
index 5483ca43..00000000
--- a/openstack_dashboard/dashboards/project/networks/subnets/tables.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CheckNetworkEditable(object):
- """Mixin class to determine the specified network is editable."""
-
- def allowed(self, request, datum=None):
- # Only administrator is allowed to create and manage subnets
- # on shared networks.
- network = self.table._get_network()
- if network.shared:
- return False
- return True
-
-
-class DeleteSubnet(CheckNetworkEditable, tables.DeleteAction):
- data_type_singular = _("Subnet")
- data_type_plural = _("Subnets")
-
- def delete(self, request, obj_id):
- try:
- api.neutron.subnet_delete(request, obj_id)
- except:
- msg = _('Failed to delete subnet %s') % obj_id
- LOG.info(msg)
- network_id = self.table.kwargs['network_id']
- redirect = reverse('horizon:project:networks:detail',
- args=[network_id])
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class CreateSubnet(CheckNetworkEditable, tables.LinkAction):
- name = "create"
- verbose_name = _("Create Subnet")
- url = "horizon:project:networks:addsubnet"
- classes = ("ajax-modal", "btn-create")
-
- def get_link_url(self, datum=None):
- network_id = self.table.kwargs['network_id']
- return reverse(self.url, args=(network_id,))
-
-
-class UpdateSubnet(CheckNetworkEditable, tables.LinkAction):
- name = "update"
- verbose_name = _("Edit Subnet")
- url = "horizon:project:networks:editsubnet"
- classes = ("ajax-modal", "btn-edit")
-
- def get_link_url(self, subnet):
- network_id = self.table.kwargs['network_id']
- return reverse(self.url, args=(network_id, subnet.id))
-
-
-class SubnetsTable(tables.DataTable):
- name = tables.Column("name", verbose_name=_("Name"),
- link='horizon:project:networks:subnets:detail')
- cidr = tables.Column("cidr", verbose_name=_("Network Address"))
- ip_version = tables.Column("ipver_str", verbose_name=_("IP Version"))
- gateway_ip = tables.Column("gateway_ip", verbose_name=_("Gateway IP"))
- failure_url = reverse_lazy('horizon:project:networks:index')
-
- def _get_network(self):
- if not hasattr(self, "_network"):
- try:
- network_id = self.kwargs['network_id']
- network = api.neutron.network_get(self.request, network_id)
- network.set_id_as_name_if_empty(length=0)
- except:
- msg = _('Unable to retrieve details for network "%s".') \
- % (network_id)
- exceptions.handle(self.request, msg, redirect=self.failure_url)
- self._network = network
- return self._network
-
- class Meta:
- name = "subnets"
- verbose_name = _("Subnets")
- table_actions = (CreateSubnet, DeleteSubnet)
- row_actions = (UpdateSubnet, DeleteSubnet)
diff --git a/openstack_dashboard/dashboards/project/networks/subnets/tabs.py b/openstack_dashboard/dashboards/project/networks/subnets/tabs.py
deleted file mode 100644
index e603cedd..00000000
--- a/openstack_dashboard/dashboards/project/networks/subnets/tabs.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "overview"
- template_name = "project/networks/subnets/_detail_overview.html"
-
- def get_context_data(self, request):
- subnet_id = self.tab_group.kwargs['subnet_id']
- try:
- subnet = api.neutron.subnet_get(self.request, subnet_id)
- except:
- redirect = reverse('horizon:project:networks:index')
- msg = _('Unable to retrieve subnet details.')
- exceptions.handle(request, msg, redirect=redirect)
- return {'subnet': subnet}
-
-
-class SubnetDetailTabs(tabs.TabGroup):
- slug = "subnet_details"
- tabs = (OverviewTab,)
diff --git a/openstack_dashboard/dashboards/project/networks/subnets/urls.py b/openstack_dashboard/dashboards/project/networks/subnets/urls.py
deleted file mode 100644
index f3aeb2e6..00000000
--- a/openstack_dashboard/dashboards/project/networks/subnets/urls.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.networks.subnets.views \
- import DetailView
-
-
-SUBNETS = r'^(?P<subnet_id>[^/]+)/%s$'
-VIEW_MOD = 'openstack_dashboard.dashboards.project.networks.subnets.views'
-
-
-urlpatterns = patterns(VIEW_MOD,
- url(SUBNETS % 'detail', DetailView.as_view(), name='detail')
-)
diff --git a/openstack_dashboard/dashboards/project/networks/subnets/views.py b/openstack_dashboard/dashboards/project/networks/subnets/views.py
deleted file mode 100644
index 1aa55d23..00000000
--- a/openstack_dashboard/dashboards/project/networks/subnets/views.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing Neutron Subnets.
-"""
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-from horizon import workflows
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.project.networks.subnets.tabs \
- import SubnetDetailTabs
-from openstack_dashboard.dashboards.project.networks.subnets.workflows \
- import CreateSubnet
-from openstack_dashboard.dashboards.project.networks.subnets.workflows \
- import UpdateSubnet
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateView(workflows.WorkflowView):
- workflow_class = CreateSubnet
-
- def get_object(self):
- if not hasattr(self, "_object"):
- try:
- network_id = self.kwargs["network_id"]
- self._object = api.neutron.network_get(self.request,
- network_id)
- self._object.set_id_as_name_if_empty()
- except:
- redirect = reverse('horizon:project:networks:index')
- msg = _("Unable to retrieve network.")
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_initial(self):
- network = self.get_object()
- return {"network_id": self.kwargs['network_id'],
- "network_name": network.name}
-
-
-class UpdateView(workflows.WorkflowView):
- workflow_class = UpdateSubnet
-
- def _get_object(self, *args, **kwargs):
- if not hasattr(self, "_object"):
- subnet_id = self.kwargs['subnet_id']
- try:
- self._object = api.neutron.subnet_get(self.request, subnet_id)
- except:
- redirect = reverse("horizon:project:networks:index")
- msg = _('Unable to retrieve subnet details')
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_initial(self):
- initial = super(UpdateView, self).get_initial()
-
- subnet = self._get_object()
-
- initial['network_id'] = self.kwargs['network_id']
- initial['subnet_id'] = subnet['id']
- initial['subnet_name'] = subnet['name']
-
- for key in ('cidr', 'ip_version', 'enable_dhcp'):
- initial[key] = subnet[key]
-
- initial['gateway_ip'] = subnet['gateway_ip'] or ''
- initial['no_gateway'] = (subnet['gateway_ip'] is None)
-
- initial['dns_nameservers'] = '\n'.join(subnet['dns_nameservers'])
- pools = ['%s,%s' % (p['start'], p['end'])
- for p in subnet['allocation_pools']]
- initial['allocation_pools'] = '\n'.join(pools)
- routes = ['%s,%s' % (r['destination'], r['nexthop'])
- for r in subnet['host_routes']]
- initial['host_routes'] = '\n'.join(routes)
-
- return initial
-
-
-class DetailView(tabs.TabView):
- tab_group_class = SubnetDetailTabs
- template_name = 'project/networks/subnets/detail.html'
diff --git a/openstack_dashboard/dashboards/project/networks/subnets/workflows.py b/openstack_dashboard/dashboards/project/networks/subnets/workflows.py
deleted file mode 100644
index c033b707..00000000
--- a/openstack_dashboard/dashboards/project/networks/subnets/workflows.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon.utils import fields
-from horizon import workflows
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.networks import workflows \
- as network_workflows
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateSubnetInfoAction(network_workflows.CreateSubnetInfoAction):
- with_subnet = forms.BooleanField(initial=True, required=False,
- widget=forms.HiddenInput())
-
- class Meta:
- name = ("Subnet")
- help_text = _('You can create a subnet associated with the '
- 'network. Advanced configuration are available '
- 'at "Subnet Detail" tab.')
-
- def clean(self):
- cleaned_data = workflows.Action.clean(self)
- self._check_subnet_data(cleaned_data)
- return cleaned_data
-
-
-class CreateSubnetInfo(network_workflows.CreateSubnetInfo):
- action_class = CreateSubnetInfoAction
- depends_on = ("network_id",)
-
-
-class CreateSubnet(network_workflows.CreateNetwork):
- slug = "create_subnet"
- name = _("Create Subnet")
- finalize_button_name = _("Create")
- success_message = _('Created subnet "%s".')
- failure_message = _('Unable to create subnet "%s".')
- default_steps = (CreateSubnetInfo,
- network_workflows.CreateSubnetDetail)
-
- def format_status_message(self, message):
- name = self.context.get('subnet_name') or self.context.get('subnet_id')
- return message % name
-
- def get_success_url(self):
- return reverse("horizon:project:networks:detail",
- args=(self.context.get('network_id'),))
-
- def get_failure_url(self):
- return reverse("horizon:project:networks:detail",
- args=(self.context.get('network_id'),))
-
- def handle(self, request, data):
- subnet = self._create_subnet(request, data)
- return True if subnet else False
-
-
-class UpdateSubnetInfoAction(CreateSubnetInfoAction):
- cidr = fields.IPField(label=_("Network Address"),
- required=False,
- initial="",
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}),
- help_text=_("Network address in CIDR format "
- "(e.g. 192.168.0.0/24)"),
- version=fields.IPv4 | fields.IPv6,
- mask=True)
- # NOTE(amotoki): When 'disabled' attribute is set for the ChoiceField
- # and ValidationError is raised for POST request, the initial value of
- # the ip_version ChoiceField is not set in the re-displayed form
- # As a result, 'IPv4' is displayed even when IPv6 is used if
- # ValidationError is detected. In addition 'required=True' check complains
- # when re-POST since the value of the ChoiceField is not set.
- # Thus now I use HiddenInput for the ip_version ChoiceField as a work
- # around.
- ip_version = forms.ChoiceField(choices=[(4, 'IPv4'), (6, 'IPv6')],
- #widget=forms.Select(
- # attrs={'disabled': 'disabled'}),
- widget=forms.HiddenInput(),
- label=_("IP Version"))
-
- gateway_ip = fields.IPField(
- label=_("Gateway IP (optional)"),
- required=False,
- initial="",
- help_text=_("IP address of Gateway (e.g. 192.168.0.254). "
- "You need to specify an explicit address "
- "to set the gateway. "
- "If you want to use no gateway, "
- "check 'Disable Gateway' below."),
- version=fields.IPv4 | fields.IPv6,
- mask=False)
- no_gateway = forms.BooleanField(label=_("Disable Gateway"),
- initial=False, required=False)
-
- class Meta:
- name = ("Subnet")
- help_text = _('You can update a subnet associated with the '
- 'network. Advanced configuration are available '
- 'at "Subnet Detail" tab.')
-
- def clean(self):
- cleaned_data = workflows.Action.clean(self)
- self._check_subnet_data(cleaned_data, is_create=False)
- return cleaned_data
-
-
-class UpdateSubnetInfo(CreateSubnetInfo):
- action_class = UpdateSubnetInfoAction
- depends_on = ("network_id", "subnet_id")
-
-
-class UpdateSubnetDetailAction(network_workflows.CreateSubnetDetailAction):
- allocation_pools = forms.CharField(widget=forms.HiddenInput(),
- required=False)
-
- class Meta:
- name = ("Subnet Detail")
- help_text = _('You can specify additional attributes for the subnet.')
-
-
-class UpdateSubnetDetail(network_workflows.CreateSubnetDetail):
- action_class = UpdateSubnetDetailAction
-
-
-class UpdateSubnet(network_workflows.CreateNetwork):
- slug = "update_subnet"
- name = _("Update Subnet")
- finalize_button_name = _("Update")
- success_message = _('Updated subnet "%s".')
- failure_message = _('Unable to update subnet "%s".')
- success_url = "horizon:project:networks:detail"
- failure_url = "horizon:project:networks:detail"
- default_steps = (UpdateSubnetInfo,
- UpdateSubnetDetail)
-
- def format_status_message(self, message):
- name = self.context.get('subnet_name') or self.context.get('subnet_id')
- return message % name
-
- def get_success_url(self):
- return reverse(self.success_url,
- args=(self.context.get('network_id'),))
-
- def _update_subnet(self, request, data):
- network_id = self.context.get('network_id')
- try:
- subnet_id = self.context.get('subnet_id')
- params = {}
- params['name'] = data['subnet_name']
- if data['no_gateway']:
- params['gateway_ip'] = None
- elif data['gateway_ip']:
- params['gateway_ip'] = data['gateway_ip']
-
- self._setup_subnet_parameters(params, data, is_create=False)
-
- subnet = api.neutron.subnet_modify(request, subnet_id, **params)
- msg = _('Subnet "%s" was successfully updated.') % data['cidr']
- LOG.debug(msg)
- return subnet
- except Exception as e:
- msg = (_('Failed to update subnet "%(sub)s": '
- ' %(reason)s') %
- {"sub": data['cidr'], "reason": e})
- redirect = reverse(self.failure_url, args=(network_id,))
- exceptions.handle(request, msg, redirect=redirect)
- return False
-
- def handle(self, request, data):
- subnet = self._update_subnet(request, data)
- return True if subnet else False
diff --git a/openstack_dashboard/dashboards/project/networks/tables.py b/openstack_dashboard/dashboards/project/networks/tables.py
deleted file mode 100644
index b5f9dc50..00000000
--- a/openstack_dashboard/dashboards/project/networks/tables.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-import logging
-
-from django.core.urlresolvers import reverse
-from django import template
-from django.template import defaultfilters as filters
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CheckNetworkEditable(object):
- """Mixin class to determine the specified network is editable."""
-
- def allowed(self, request, datum=None):
- # Only administrator is allowed to create and manage shared networks.
- if datum and datum.shared:
- return False
- return True
-
-
-class DeleteNetwork(CheckNetworkEditable, tables.DeleteAction):
- data_type_singular = _("Network")
- data_type_plural = _("Networks")
-
- def delete(self, request, network_id):
- try:
- # Retrieve existing subnets belonging to the network.
- subnets = api.neutron.subnet_list(request, network_id=network_id)
- LOG.debug('Network %s has subnets: %s' %
- (network_id, [s.id for s in subnets]))
- for s in subnets:
- api.neutron.subnet_delete(request, s.id)
- LOG.debug('Deleted subnet %s' % s.id)
-
- api.neutron.network_delete(request, network_id)
- LOG.debug('Deleted network %s successfully' % network_id)
- except:
- msg = _('Failed to delete network %s') % network_id
- LOG.info(msg)
- redirect = reverse("horizon:project:networks:index")
- exceptions.handle(request, msg, redirect=redirect)
-
-
-class CreateNetwork(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Network")
- url = "horizon:project:networks:create"
- classes = ("ajax-modal", "btn-create")
-
-
-class EditNetwork(CheckNetworkEditable, tables.LinkAction):
- name = "update"
- verbose_name = _("Edit Network")
- url = "horizon:project:networks:update"
- classes = ("ajax-modal", "btn-edit")
-
-
-class CreateSubnet(CheckNetworkEditable, tables.LinkAction):
- name = "subnet"
- verbose_name = _("Add Subnet")
- url = "horizon:project:networks:addsubnet"
- classes = ("ajax-modal", "btn-create")
-
-
-def get_subnets(network):
- template_name = 'project/networks/_network_ips.html'
- context = {"subnets": network.subnets}
- return template.loader.render_to_string(template_name, context)
-
-
-class NetworksTable(tables.DataTable):
- name = tables.Column("name",
- verbose_name=_("Name"),
- link='horizon:project:networks:detail')
- subnets = tables.Column(get_subnets,
- verbose_name=_("Subnets Associated"),)
- shared = tables.Column("shared", verbose_name=_("Shared"),
- filters=(filters.yesno, filters.capfirst))
- status = tables.Column("status", verbose_name=_("Status"))
- admin_state = tables.Column("admin_state",
- verbose_name=_("Admin State"))
-
- class Meta:
- name = "networks"
- verbose_name = _("Networks")
- table_actions = (CreateNetwork, DeleteNetwork)
- row_actions = (EditNetwork, CreateSubnet, DeleteNetwork)
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/_create.html b/openstack_dashboard/dashboards/project/networks/templates/networks/_create.html
deleted file mode 100644
index 0377dd10..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/_create.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}create_network_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:networks:create' %}{% endblock %}
-
-{% block modal-header %}{% trans "Create Network" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "Select a name for your network."%}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Network" %}" />
- <a href="{% url 'horizon:project:networks:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/_detail_overview.html b/openstack_dashboard/dashboards/project/networks/templates/networks/_detail_overview.html
deleted file mode 100644
index e3d07c42..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/_detail_overview.html
+++ /dev/null
@@ -1,28 +0,0 @@
-{% load i18n sizeformat %}
-
-<h3>{% trans "Network Overview" %}</h3>
-
-<div class="info detail">
- <dl>
- <dt>{% trans "Name" %}</dt>
- <dd>{{ network.name|default:_("None") }}</dd>
- <dt>{% trans "ID" %}</dt>
- <dd>{{ network.id|default:_("None") }}</dd>
- <dt>{% trans "Project ID" %}</dt>
- <dd>{{ network.tenant_id|default:"-" }}</dd>
- <dt>{% trans "Status" %}</dt>
- <dd>{{ network.status|default:_("Unknown") }}</dd>
- <dt>{% trans "Admin State" %}</dt>
- <dd>{{ network.admin_state|default:_("Unknown") }}</dd>
- <dt>{% trans "Shared" %}</dt>
- <dd>{{ network.shared|yesno|capfirst }}</dd>
- <dt>{% trans "External Network" %}</dt>
- <dd>{{ network.router__external|yesno|capfirst }}</dd>
- {% if network.provider__network_type %}
- <dt>{% trans "Provider Network" %}</dt>
- <dd>{% trans "Network Type" %}: {{ network.provider__network_type|default:_("Unknown") }}</dd>
- <dd>{% trans "Physical Network" %}: {{ network.provider__physical_network|default:"-" }}</dd>
- <dd>{% trans "Segmentation ID" %}: {{ network.provider__segmentation_id|default:"-" }}</dd>
- {% endif %}
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/_network_ips.html b/openstack_dashboard/dashboards/project/networks/templates/networks/_network_ips.html
deleted file mode 100644
index a80e7479..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/_network_ips.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{% for subnet in subnets %}
-<ul>
- <li>
- {% if subnet.name|length > 0 %}
- <b>{{ subnet.name }}</b>
- {% endif %}
- {{ subnet.cidr }}
- </li>
-</ul>
-{% endfor %}
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/_update.html b/openstack_dashboard/dashboards/project/networks/templates/networks/_update.html
deleted file mode 100644
index ceb8e6cd..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/_update.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_network_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:networks:update' network_id %}{% endblock %}
-
-{% block modal-header %}{% trans "Edit Network" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "You may update the editable properties of your network here." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
- <a href="{% url 'horizon:project:networks:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/detail.html b/openstack_dashboard/dashboards/project/networks/templates/networks/detail.html
deleted file mode 100644
index d6773feb..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/detail.html
+++ /dev/null
@@ -1,18 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Network Detail"%}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Network Detail: ")|add:network.name %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "project/networks/_detail_overview.html" %}
- <hr>
- <div id="subnets">
- {{ subnets_table.render }}
- </div>
- <div id="ports">
- {{ ports_table.render }}
- </div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/index.html b/openstack_dashboard/dashboards/project/networks/templates/networks/index.html
deleted file mode 100644
index d458220a..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Networks" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Networks") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/ports/_detail_overview.html b/openstack_dashboard/dashboards/project/networks/templates/networks/ports/_detail_overview.html
deleted file mode 100644
index 56152156..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/ports/_detail_overview.html
+++ /dev/null
@@ -1,44 +0,0 @@
-{% load i18n sizeformat %}
-{% load url from future %}
-
-<h3>{% trans "Port Overview" %}</h3>
-
-<div class="info row-fluid detail">
- <h4>{% trans "Port" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Name" %}</dt>
- <dd>{{ port.name|default:_("None") }}</dd>
- <dt>{% trans "ID" %}</dt>
- <dd>{{ port.id|default:_("None") }}</dd>
- {% url 'horizon:project:networks:detail' port.network_id as network_url %}
- <dt>{% trans "Network ID" %}</dt>
- <dd><a href="{{ network_url }}">{{ port.network_id|default:_("None") }}</a></dd>
- <dt>{% trans "Project ID" %}</dt>
- <dd>{{ port.tenant_id|default:"-" }}</dd>
- <dt>{% trans "Fixed IP" %}</dt>
- <dd>
- {% if port.fixed_ips.items|length > 1 %}
- {% for ip in port.fixed_ips %}
- <b>{% trans "IP address:" %}</b> {{ ip.ip_address }},
- <b>{% trans "Subnet ID" %}</b> {{ ip.subnet_id }}<br>
- {% endfor %}
- {% else %}
- "None"
- {% endif %}
- </dd>
- <dt>{% trans "Mac Address" %}</dt>
- <dd>{{ port.mac_address|default:_("None") }}</dd>
- <dt>{% trans "Status" %}</dt>
- <dd>{{ port.status|default:_("None") }}</dd>
- <dt>{% trans "Admin State" %}</dt>
- <dd>{{ port.admin_state|default:_("None") }}</dd>
- <dt>{% trans "Attached Device" %}</dt>
- {% if port.device_id|length > 1 or port.device_owner %}
- <dd><b>{% trans "Device Owner" %}</b>: {{ port.device_owner|default:_("None") }}</dd>
- <dd><b>{% trans "Device ID" %}</b>: {{ port.device_id|default:"-" }}</dd>
- {% else %}
- <dd>No attached device</dd>
- {% endif %}
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/ports/_port_ips.html b/openstack_dashboard/dashboards/project/networks/templates/networks/ports/_port_ips.html
deleted file mode 100644
index bfd5ea9f..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/ports/_port_ips.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% for ip in ips %}
-<ul>
- <li>
- {{ ip.ip_address }}
- </li>
-</ul>
-{% endfor %}
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/ports/_update.html b/openstack_dashboard/dashboards/project/networks/templates/networks/ports/_update.html
deleted file mode 100644
index 8ca45f0f..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/ports/_update.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}update_port_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:networks:editport' network_id port_id %}{% endblock %}
-
-{% block modal-header %}{% trans "Edit Port" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <dl>
- <dt>{% trans "ID" %}</dt>
- <dd>{{ port_id }}</dd>
- </dl>
- <hr>
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "You may update the editable properties of your port here." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Save Changes" %}" />
- <a href="{% url 'horizon:project:networks:detail' network_id %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/ports/detail.html b/openstack_dashboard/dashboards/project/networks/templates/networks/ports/detail.html
deleted file mode 100644
index 634c6d67..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/ports/detail.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Port Detail"%}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Port Detail") %}
-{% endblock page_header %}
-
-{% block main %}
-<div id="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/ports/update.html b/openstack_dashboard/dashboards/project/networks/templates/networks/ports/update.html
deleted file mode 100644
index f6b93229..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/ports/update.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Update Port" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Update Port") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/networks/ports/_update.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/_detail_overview.html b/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/_detail_overview.html
deleted file mode 100644
index 96a282c3..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/_detail_overview.html
+++ /dev/null
@@ -1,50 +0,0 @@
-{% load i18n sizeformat %}
-{% load url from future %}
-
-<h3>{% trans "Subnet Overview" %}</h3>
-
-<div class="info row-fluid detail">
- <h4>{% trans "Subnet" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Name" %}</dt>
- <dd>{{ subnet.name|default:_("None") }}</dd>
- <dt>{% trans "ID" %}</dt>
- <dd>{{ subnet.id|default:_("None") }}</dd>
- {% url 'horizon:project:networks:detail' subnet.network_id as network_url %}
- <dt>{% trans "Network ID" %}</dt>
- <dd><a href="{{ network_url }}">{{ subnet.network_id|default:_("None") }}</a></dd>
- <dt>{% trans "IP version" %}</dt>
- <dd>{{ subnet.ipver_str|default:"-" }}</dd>
- <dt>{% trans "CIDR" %}</dt>
- <dd>{{ subnet.cidr|default:_("None") }}</dd>
- <dt>{% trans "IP allocation pool" %}</dt>
- <dd>
- {% for pool in subnet.allocation_pools %}
- {% trans "Start" %} {{ pool.start }}
- {% trans " - End" %} {{ pool.end }}<br>
- {% endfor %}
- </dd>
- <dt>{% trans "DHCP Enable" %}<dt>
- <dd>{{ subnet.enable_dhcp|yesno|capfirst }}</dd>
- <dt>{% trans "Gateway IP" %}</dt>
- <dd>{{ subnet.gateway_ip|default:"-" }}</dd>
- <dt>{% trans "Additional routes" %}</dt>
- <dd>
- {% for route in subnet.host_routes %}
- {% trans "Destination" %} {{ route.destination }}
- {% trans " : Next hop" %} {{ route.nexthop }}<br>
- {% empty %}
- {% trans "None" %}
- {% endfor %}
- </dd>
- <dt>{% trans "DNS name server" %}</dt>
- <dd>
- {% for dns in subnet.dns_nameservers %}
- {{ dns }}
- {% empty %}
- {% trans "None" %}
- {% endfor %}
- </dd>
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/detail.html b/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/detail.html
deleted file mode 100644
index c4e35bd0..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/detail.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Subnet Detail"%}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Subnet Detail") %}
-{% endblock page_header %}
-
-{% block main %}
-<div id="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/index.html b/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/index.html
deleted file mode 100644
index 833399a2..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/subnets/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Network" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Network") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/networks/templates/networks/update.html b/openstack_dashboard/dashboards/project/networks/templates/networks/update.html
deleted file mode 100644
index 07f5993f..00000000
--- a/openstack_dashboard/dashboards/project/networks/templates/networks/update.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Update Network" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Update Network") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/networks/_update.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/networks/tests.py b/openstack_dashboard/dashboards/project/networks/tests.py
deleted file mode 100644
index 1a0bc6ac..00000000
--- a/openstack_dashboard/dashboards/project/networks/tests.py
+++ /dev/null
@@ -1,1335 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.core.urlresolvers import reverse
-from django import http
-from django.utils.html import escape
-
-from horizon.workflows.views import WorkflowView
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-from openstack_dashboard.dashboards.project.networks.workflows \
- import CreateNetwork
-
-
-INDEX_URL = reverse('horizon:project:networks:index')
-
-
-def form_data_subnet(subnet,
- name=None, cidr=None, ip_version=None,
- gateway_ip='', enable_dhcp=None,
- allocation_pools=None,
- dns_nameservers=None,
- host_routes=None):
- def get_value(value, default):
- return default if value is None else value
-
- data = {}
- data['subnet_name'] = get_value(name, subnet.name)
- data['cidr'] = get_value(cidr, subnet.cidr)
- data['ip_version'] = get_value(ip_version, subnet.ip_version)
-
- gateway_ip = subnet.gateway_ip if gateway_ip == '' else gateway_ip
- data['gateway_ip'] = gateway_ip or ''
- data['no_gateway'] = (gateway_ip is None)
-
- data['enable_dhcp'] = get_value(enable_dhcp, subnet.enable_dhcp)
-
- pools = get_value(allocation_pools, subnet.allocation_pools)
- data['allocation_pools'] = _str_allocation_pools(pools)
- nameservers = get_value(dns_nameservers, subnet.dns_nameservers)
- data['dns_nameservers'] = _str_dns_nameservers(nameservers)
- routes = get_value(host_routes, subnet.host_routes)
- data['host_routes'] = _str_host_routes(routes)
-
- return data
-
-
-def form_data_no_subnet():
- return {'subnet_name': '',
- 'cidr': '',
- 'ip_version': 4,
- 'gateway_ip': '',
- 'no_gateway': False,
- 'enable_dhcp': True,
- 'allocation_pools': '',
- 'dns_nameservers': '',
- 'host_routes': ''}
-
-
-def _str_allocation_pools(allocation_pools):
- if isinstance(allocation_pools, str):
- return allocation_pools
- return '\n'.join(['%s,%s' % (pool['start'], pool['end'])
- for pool in allocation_pools])
-
-
-def _str_dns_nameservers(dns_nameservers):
- if isinstance(dns_nameservers, str):
- return dns_nameservers
- return '\n'.join(dns_nameservers)
-
-
-def _str_host_routes(host_routes):
- if isinstance(host_routes, str):
- return host_routes
- return '\n'.join(['%s,%s' % (route['destination'], route['nexthop'])
- for route in host_routes])
-
-
-class NetworkTests(test.TestCase):
-
- @test.create_stubs({api.neutron: ('network_list',)})
- def test_index(self):
- api.neutron.network_list(
- IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False).AndReturn(self.networks.list())
- api.neutron.network_list(
- IsA(http.HttpRequest),
- shared=True).AndReturn([])
-
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
-
- self.assertTemplateUsed(res, 'project/networks/index.html')
- networks = res.context['networks_table'].data
- self.assertItemsEqual(networks, self.networks.list())
-
- @test.create_stubs({api.neutron: ('network_list',)})
- def test_index_network_list_exception(self):
- api.neutron.network_list(
- IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- shared=False).AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
-
- self.assertTemplateUsed(res, 'project/networks/index.html')
- self.assertEqual(len(res.context['networks_table'].data), 0)
- self.assertMessageCount(res, error=1)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_list',
- 'port_list',)})
- def test_network_detail(self):
- network_id = self.networks.first().id
- api.neutron.network_get(IsA(http.HttpRequest), network_id)\
- .AndReturn(self.networks.first())
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.subnets.first()])
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.ports.first()])
- api.neutron.network_get(IsA(http.HttpRequest), network_id)\
- .AndReturn(self.networks.first())
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:project:networks:detail',
- args=[network_id]))
-
- self.assertTemplateUsed(res, 'project/networks/detail.html')
- subnets = res.context['subnets_table'].data
- ports = res.context['ports_table'].data
- self.assertItemsEqual(subnets, [self.subnets.first()])
- self.assertItemsEqual(ports, [self.ports.first()])
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_list',
- 'port_list',)})
- def test_network_detail_network_exception(self):
- network_id = self.networks.first().id
- api.neutron.network_get(IsA(http.HttpRequest), network_id)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:networks:detail', args=[network_id])
- res = self.client.get(url)
-
- redir_url = INDEX_URL
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_list',
- 'port_list',)})
- def test_network_detail_subnet_exception(self):
- network_id = self.networks.first().id
- api.neutron.network_get(IsA(http.HttpRequest), network_id).\
- AndReturn(self.networks.first())
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id).\
- AndRaise(self.exceptions.neutron)
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id).\
- AndReturn([self.ports.first()])
- # Called from SubnetTable
- api.neutron.network_get(IsA(http.HttpRequest), network_id).\
- AndReturn(self.networks.first())
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:project:networks:detail',
- args=[network_id]))
-
- self.assertTemplateUsed(res, 'project/networks/detail.html')
- subnets = res.context['subnets_table'].data
- ports = res.context['ports_table'].data
- self.assertEqual(len(subnets), 0)
- self.assertItemsEqual(ports, [self.ports.first()])
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_list',
- 'port_list',)})
- def test_network_detail_port_exception(self):
- network_id = self.networks.first().id
- api.neutron.network_get(IsA(http.HttpRequest), network_id).\
- AndReturn(self.networks.first())
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id).\
- AndReturn([self.subnets.first()])
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id).\
- AndRaise(self.exceptions.neutron)
- # Called from SubnetTable
- api.neutron.network_get(IsA(http.HttpRequest), network_id).\
- AndReturn(self.networks.first())
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:project:networks:detail',
- args=[network_id]))
-
- self.assertTemplateUsed(res, 'project/networks/detail.html')
- subnets = res.context['subnets_table'].data
- ports = res.context['ports_table'].data
- self.assertItemsEqual(subnets, [self.subnets.first()])
- self.assertEqual(len(ports), 0)
-
- def test_network_create_get(self):
- # no api methods are called.
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:networks:create')
- res = self.client.get(url)
-
- workflow = res.context['workflow']
- self.assertTemplateUsed(res, WorkflowView.template_name)
- self.assertEqual(workflow.name, CreateNetwork.name)
- expected_objs = ['<CreateNetworkInfo: createnetworkinfoaction>',
- '<CreateSubnetInfo: createsubnetinfoaction>',
- '<CreateSubnetDetail: createsubnetdetailaction>']
- self.assertQuerysetEqual(workflow.steps, expected_objs)
-
- @test.create_stubs({api.neutron: ('network_create',)})
- def test_network_create_post(self):
- network = self.networks.first()
- api.neutron.network_create(IsA(http.HttpRequest), name=network.name,
- admin_state_up=network.admin_state_up)\
- .AndReturn(network)
- self.mox.ReplayAll()
-
- form_data = {'net_name': network.name,
- 'admin_state': network.admin_state_up,
- # subnet
- 'with_subnet': False}
- form_data.update(form_data_no_subnet())
- url = reverse('horizon:project:networks:create')
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_create',
- 'subnet_create',)})
- def test_network_create_post_with_subnet(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_create(IsA(http.HttpRequest), name=network.name,
- admin_state_up=network.admin_state_up)\
- .AndReturn(network)
- api.neutron.subnet_create(IsA(http.HttpRequest),
- network_id=network.id,
- name=subnet.name,
- cidr=subnet.cidr,
- ip_version=subnet.ip_version,
- gateway_ip=subnet.gateway_ip,
- enable_dhcp=subnet.enable_dhcp)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- form_data = {'net_name': network.name,
- 'admin_state': network.admin_state_up,
- 'with_subnet': True}
- form_data.update(form_data_subnet(subnet, allocation_pools=[]))
- url = reverse('horizon:project:networks:create')
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_create',)})
- def test_network_create_post_network_exception(self):
- network = self.networks.first()
- api.neutron.network_create(IsA(http.HttpRequest), name=network.name,
- admin_state_up=network.admin_state_up)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- form_data = {'net_name': network.name,
- 'admin_state': network.admin_state_up,
- # subnet
- 'with_subnet': False}
- form_data.update(form_data_no_subnet())
- url = reverse('horizon:project:networks:create')
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_create',)})
- def test_network_create_post_with_subnet_network_exception(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_create(IsA(http.HttpRequest), name=network.name,
- admin_state_up=network.admin_state_up)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- form_data = {'net_name': network.name,
- 'admin_state': network.admin_state_up,
- 'with_subnet': True}
- form_data.update(form_data_subnet(subnet, allocation_pools=[]))
- url = reverse('horizon:project:networks:create')
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_create',
- 'network_delete',
- 'subnet_create',)})
- def test_network_create_post_with_subnet_subnet_exception(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_create(IsA(http.HttpRequest), name=network.name,
- admin_state_up=network.admin_state_up)\
- .AndReturn(network)
- api.neutron.subnet_create(IsA(http.HttpRequest),
- network_id=network.id,
- name=subnet.name,
- cidr=subnet.cidr,
- ip_version=subnet.ip_version,
- gateway_ip=subnet.gateway_ip,
- enable_dhcp=subnet.enable_dhcp)\
- .AndRaise(self.exceptions.neutron)
- api.neutron.network_delete(IsA(http.HttpRequest),
- network.id)
- self.mox.ReplayAll()
-
- form_data = {'net_name': network.name,
- 'admin_state': network.admin_state_up,
- 'with_subnet': True}
- form_data.update(form_data_subnet(subnet, allocation_pools=[]))
- url = reverse('horizon:project:networks:create')
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- def test_network_create_post_with_subnet_nocidr(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- self.mox.ReplayAll()
-
- form_data = {'net_name': network.name,
- 'admin_state': network.admin_state_up,
- 'with_subnet': True}
- form_data.update(form_data_subnet(subnet, cidr='',
- allocation_pools=[]))
- url = reverse('horizon:project:networks:create')
- res = self.client.post(url, form_data)
-
- self.assertContains(res, escape('Specify "Network Address" or '
- 'clear "Create Subnet" checkbox.'))
-
- def test_network_create_post_with_subnet_cidr_without_mask(self):
- network = self.networks.first()
- subnet = self.subnets.first()
-
- form_data = {'net_name': network.name,
- 'admin_state': network.admin_state_up,
- 'with_subnet': True}
- form_data.update(form_data_subnet(subnet, cidr='10.0.0.0',
- allocation_pools=[]))
- url = reverse('horizon:project:networks:create')
- res = self.client.post(url, form_data)
-
- expected_msg = "The subnet in the Network Address is too small (/32)."
- self.assertContains(res, expected_msg)
-
- def test_network_create_post_with_subnet_cidr_inconsistent(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- self.mox.ReplayAll()
-
- # dummy IPv6 address
- cidr = '2001:0DB8:0:CD30:123:4567:89AB:CDEF/60'
- form_data = {'net_name': network.name,
- 'admin_state': network.admin_state_up,
- 'with_subnet': True}
- form_data.update(form_data_subnet(subnet, cidr=cidr,
- allocation_pools=[]))
- url = reverse('horizon:project:networks:create')
- res = self.client.post(url, form_data)
-
- expected_msg = 'Network Address and IP version are inconsistent.'
- self.assertContains(res, expected_msg)
-
- def test_network_create_post_with_subnet_gw_inconsistent(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- self.mox.ReplayAll()
-
- # dummy IPv6 address
- gateway_ip = '2001:0DB8:0:CD30:123:4567:89AB:CDEF'
- form_data = {'net_name': network.name,
- 'admin_state': network.admin_state_up,
- 'with_subnet': True}
- form_data.update(form_data_subnet(subnet, gateway_ip=gateway_ip,
- allocation_pools=[]))
- url = reverse('horizon:project:networks:create')
- res = self.client.post(url, form_data)
-
- self.assertContains(res, 'Gateway IP and IP version are inconsistent.')
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_network_update_get(self):
- network = self.networks.first()
- api.neutron.network_get(IsA(http.HttpRequest), network.id)\
- .AndReturn(network)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:networks:update', args=[network.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, 'project/networks/update.html')
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_network_update_get_exception(self):
- network = self.networks.first()
- api.neutron.network_get(IsA(http.HttpRequest), network.id)\
- .AndRaise(self.exceptions.neutron)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:networks:update', args=[network.id])
- res = self.client.get(url)
-
- redir_url = INDEX_URL
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_modify',
- 'network_get',)})
- def test_network_update_post(self):
- network = self.networks.first()
- api.neutron.network_modify(IsA(http.HttpRequest), network.id,
- name=network.name,
- admin_state_up=network.admin_state_up)\
- .AndReturn(network)
- api.neutron.network_get(IsA(http.HttpRequest), network.id)\
- .AndReturn(network)
- self.mox.ReplayAll()
-
- form_data = {'network_id': network.id,
- 'name': network.name,
- 'admin_state': network.admin_state_up,
- 'tenant_id': network.tenant_id}
- url = reverse('horizon:project:networks:update', args=[network.id])
- res = self.client.post(url, form_data)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_modify',
- 'network_get',)})
- def test_network_update_post_exception(self):
- network = self.networks.first()
- api.neutron.network_modify(IsA(http.HttpRequest), network.id,
- name=network.name,
- admin_state_up=network.admin_state_up)\
- .AndRaise(self.exceptions.neutron)
- api.neutron.network_get(IsA(http.HttpRequest), network.id)\
- .AndReturn(network)
- self.mox.ReplayAll()
-
- form_data = {'network_id': network.id,
- 'name': network.name,
- 'admin_state': network.admin_state_up,
- 'tenant_id': network.tenant_id}
- url = reverse('horizon:project:networks:update', args=[network.id])
- res = self.client.post(url, form_data)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_list',
- 'subnet_list',
- 'network_delete')})
- def test_delete_network_no_subnet(self):
- network = self.networks.first()
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=network.tenant_id,
- shared=False)\
- .AndReturn([network])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True)\
- .AndReturn([])
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network.id)\
- .AndReturn([])
- api.neutron.network_delete(IsA(http.HttpRequest), network.id)
-
- self.mox.ReplayAll()
-
- form_data = {'action': 'networks__delete__%s' % network.id}
- res = self.client.post(INDEX_URL, form_data)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_list',
- 'subnet_list',
- 'network_delete',
- 'subnet_delete')})
- def test_delete_network_with_subnet(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=network.tenant_id,
- shared=False)\
- .AndReturn([network])
- api.neutron.network_list(IsA(http.HttpRequest), shared=True)\
- .AndReturn([])
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network.id)\
- .AndReturn([subnet])
- api.neutron.subnet_delete(IsA(http.HttpRequest), subnet.id)
- api.neutron.network_delete(IsA(http.HttpRequest), network.id)
-
- self.mox.ReplayAll()
-
- form_data = {'action': 'networks__delete__%s' % network.id}
- res = self.client.post(INDEX_URL, form_data)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_list',
- 'subnet_list',
- 'network_delete',
- 'subnet_delete')})
- def test_delete_network_exception(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_list(IsA(http.HttpRequest),
- tenant_id=network.tenant_id,
- shared=False)\
- .AndReturn([network])
- api.neutron.network_list(IsA(http.HttpRequest),
- shared=True)\
- .AndReturn([])
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network.id)\
- .AndReturn([subnet])
- api.neutron.subnet_delete(IsA(http.HttpRequest), subnet.id)
- api.neutron.network_delete(IsA(http.HttpRequest), network.id)\
- .AndRaise(self.exceptions.neutron)
-
- self.mox.ReplayAll()
-
- form_data = {'action': 'networks__delete__%s' % network.id}
- res = self.client.post(INDEX_URL, form_data)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
-
-class NetworkSubnetTests(test.TestCase):
-
- @test.create_stubs({api.neutron: ('subnet_get',)})
- def test_subnet_detail(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(self.subnets.first())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:networks:subnets:detail',
- args=[subnet.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, 'project/networks/subnets/detail.html')
- self.assertEqual(res.context['subnet'].id, subnet.id)
-
- @test.create_stubs({api.neutron: ('subnet_get',)})
- def test_subnet_detail_exception(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndRaise(self.exceptions.neutron)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:networks:subnets:detail',
- args=[subnet.id])
- res = self.client.get(url)
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_get(self):
- network = self.networks.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:networks:addsubnet',
- args=[network.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_create',)})
- def test_subnet_create_post(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.subnet_create(IsA(http.HttpRequest),
- network_id=network.id,
- name=subnet.name,
- cidr=subnet.cidr,
- ip_version=subnet.ip_version,
- gateway_ip=subnet.gateway_ip,
- enable_dhcp=subnet.enable_dhcp,
- allocation_pools=subnet.allocation_pools)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet)
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- redir_url = reverse('horizon:project:networks:detail',
- args=[subnet.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_create',)})
- def test_subnet_create_post_with_additional_attributes(self):
- network = self.networks.list()[1]
- subnet = self.subnets.list()[1]
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.subnet_create(IsA(http.HttpRequest),
- network_id=network.id,
- name=subnet.name,
- cidr=subnet.cidr,
- ip_version=subnet.ip_version,
- gateway_ip=subnet.gateway_ip,
- enable_dhcp=subnet.enable_dhcp,
- allocation_pools=subnet.allocation_pools,
- dns_nameservers=subnet.dns_nameservers,
- host_routes=subnet.host_routes)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet)
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- redir_url = reverse('horizon:project:networks:detail',
- args=[subnet.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_create',)})
- def test_subnet_create_post_with_additional_attributes_no_gateway(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.subnet_create(IsA(http.HttpRequest),
- network_id=network.id,
- name=subnet.name,
- cidr=subnet.cidr,
- ip_version=subnet.ip_version,
- gateway_ip=None,
- enable_dhcp=subnet.enable_dhcp,
- allocation_pools=subnet.allocation_pools)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet, gateway_ip=None)
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- redir_url = reverse('horizon:project:networks:detail',
- args=[subnet.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_create',)})
- def test_subnet_create_post_network_exception(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet,
- allocation_pools=[])
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('network_get',
- 'subnet_create',)})
- def test_subnet_create_post_subnet_exception(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- api.neutron.subnet_create(IsA(http.HttpRequest),
- network_id=network.id,
- name=subnet.name,
- cidr=subnet.cidr,
- ip_version=subnet.ip_version,
- gateway_ip=subnet.gateway_ip,
- enable_dhcp=subnet.enable_dhcp)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet,
- allocation_pools=[])
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- redir_url = reverse('horizon:project:networks:detail',
- args=[subnet.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_cidr_inconsistent(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- self.mox.ReplayAll()
-
- # dummy IPv6 address
- cidr = '2001:0DB8:0:CD30:123:4567:89AB:CDEF/60'
- form_data = form_data_subnet(subnet, cidr=cidr,
- allocation_pools=[])
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- expected_msg = 'Network Address and IP version are inconsistent.'
- self.assertFormErrors(res, 1, expected_msg)
- self.assertTemplateUsed(res, WorkflowView.template_name)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_gw_inconsistent(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id)\
- .AndReturn(self.networks.first())
- self.mox.ReplayAll()
-
- # dummy IPv6 address
- gateway_ip = '2001:0DB8:0:CD30:123:4567:89AB:CDEF'
- form_data = form_data_subnet(subnet, gateway_ip=gateway_ip,
- allocation_pools=[])
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res, 'Gateway IP and IP version are inconsistent.')
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_invalid_pools_start_only(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id).AndReturn(network)
- self.mox.ReplayAll()
-
- # Start only allocation_pools
- allocation_pools = '10.0.0.2'
- form_data = form_data_subnet(subnet,
- allocation_pools=allocation_pools)
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'Start and end addresses must be specified '
- '(value=%s)' % allocation_pools)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_invalid_pools_three_entries(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id).AndReturn(network)
- self.mox.ReplayAll()
-
- # pool with three entries
- allocation_pools = '10.0.0.2,10.0.0.3,10.0.0.4'
- form_data = form_data_subnet(subnet,
- allocation_pools=allocation_pools)
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'Start and end addresses must be specified '
- '(value=%s)' % allocation_pools)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_invalid_pools_invalid_address(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id).AndReturn(network)
- self.mox.ReplayAll()
-
- # end address is not a valid IP address
- allocation_pools = '10.0.0.2,invalid_address'
- form_data = form_data_subnet(subnet,
- allocation_pools=allocation_pools)
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'allocation_pools: Invalid IP address '
- '(value=%s)' % allocation_pools.split(',')[1])
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_invalid_pools_ip_network(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id).AndReturn(network)
- self.mox.ReplayAll()
-
- # start address is CIDR
- allocation_pools = '10.0.0.2/24,10.0.0.5'
- form_data = form_data_subnet(subnet,
- allocation_pools=allocation_pools)
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'allocation_pools: Invalid IP address '
- '(value=%s)' % allocation_pools.split(',')[0])
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_invalid_pools_start_larger_than_end(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id).AndReturn(network)
- self.mox.ReplayAll()
-
- # start address is larger than end address
- allocation_pools = '10.0.0.254,10.0.0.2'
- form_data = form_data_subnet(subnet,
- allocation_pools=allocation_pools)
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'Start address is larger than end address '
- '(value=%s)' % allocation_pools)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_invalid_nameservers(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id).AndReturn(network)
- self.mox.ReplayAll()
-
- # invalid DNS server address
- dns_nameservers = ['192.168.0.2', 'invalid_address']
- form_data = form_data_subnet(subnet, dns_nameservers=dns_nameservers,
- allocation_pools=[])
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'dns_nameservers: Invalid IP address '
- '(value=%s)' % dns_nameservers[1])
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_invalid_routes_destination_only(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id).AndReturn(network)
- self.mox.ReplayAll()
-
- # Start only host_route
- host_routes = '192.168.0.0/24'
- form_data = form_data_subnet(subnet,
- allocation_pools=[],
- host_routes=host_routes)
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'Host Routes format error: '
- 'Destination CIDR and nexthop must be specified '
- '(value=%s)' % host_routes)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_invalid_routes_three_entries(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id).AndReturn(network)
- self.mox.ReplayAll()
-
- # host_route with three entries
- host_routes = 'aaaa,bbbb,cccc'
- form_data = form_data_subnet(subnet,
- allocation_pools=[],
- host_routes=host_routes)
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'Host Routes format error: '
- 'Destination CIDR and nexthop must be specified '
- '(value=%s)' % host_routes)
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_invalid_routes_invalid_destination(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id).AndReturn(network)
- self.mox.ReplayAll()
-
- # invalid destination network
- host_routes = '172.16.0.0/64,10.0.0.253'
- form_data = form_data_subnet(subnet,
- host_routes=host_routes,
- allocation_pools=[])
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'host_routes: Invalid IP address '
- '(value=%s)' % host_routes.split(',')[0])
-
- @test.create_stubs({api.neutron: ('network_get',)})
- def test_subnet_create_post_invalid_routes_nexthop_ip_network(self):
- network = self.networks.first()
- subnet = self.subnets.first()
- api.neutron.network_get(IsA(http.HttpRequest),
- network.id).AndReturn(network)
- self.mox.ReplayAll()
-
- # nexthop is not an IP address
- host_routes = '172.16.0.0/24,10.0.0.253/24'
- form_data = form_data_subnet(subnet,
- host_routes=host_routes,
- allocation_pools=[])
- url = reverse('horizon:project:networks:addsubnet',
- args=[subnet.network_id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'host_routes: Invalid IP address '
- '(value=%s)' % host_routes.split(',')[1])
-
- @test.create_stubs({api.neutron: ('subnet_modify',
- 'subnet_get',)})
- def test_subnet_update_post(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(subnet)
- api.neutron.subnet_modify(IsA(http.HttpRequest), subnet.id,
- name=subnet.name,
- gateway_ip=subnet.gateway_ip,
- enable_dhcp=subnet.enable_dhcp,
- dns_nameservers=[],
- host_routes=[])\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet,
- allocation_pools=[])
- url = reverse('horizon:project:networks:editsubnet',
- args=[subnet.network_id, subnet.id])
- res = self.client.post(url, form_data)
-
- redir_url = reverse('horizon:project:networks:detail',
- args=[subnet.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('subnet_modify',
- 'subnet_get',)})
- def test_subnet_update_post_no_gateway(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(subnet)
- api.neutron.subnet_modify(IsA(http.HttpRequest), subnet.id,
- name=subnet.name,
- gateway_ip=None,
- enable_dhcp=subnet.enable_dhcp,
- dns_nameservers=[],
- host_routes=[])\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet,
- gateway_ip=None,
- allocation_pools=[])
- url = reverse('horizon:project:networks:editsubnet',
- args=[subnet.network_id, subnet.id])
- res = self.client.post(url, form_data)
-
- redir_url = reverse('horizon:project:networks:detail',
- args=[subnet.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('subnet_modify',
- 'subnet_get',)})
- def test_subnet_update_post_with_additional_attributes(self):
- subnet = self.subnets.list()[1]
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(subnet)
- api.neutron.subnet_modify(IsA(http.HttpRequest), subnet.id,
- name=subnet.name,
- gateway_ip=subnet.gateway_ip,
- enable_dhcp=False,
- dns_nameservers=subnet.dns_nameservers,
- host_routes=subnet.host_routes)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- form_data = form_data_subnet(subnet,
- enable_dhcp=False)
- url = reverse('horizon:project:networks:editsubnet',
- args=[subnet.network_id, subnet.id])
- res = self.client.post(url, form_data)
-
- redir_url = reverse('horizon:project:networks:detail',
- args=[subnet.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('subnet_modify',
- 'subnet_get',)})
- def test_subnet_update_post_gw_inconsistent(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- # dummy IPv6 address
- gateway_ip = '2001:0DB8:0:CD30:123:4567:89AB:CDEF'
- form_data = form_data_subnet(subnet, gateway_ip=gateway_ip,
- allocation_pools=[])
- url = reverse('horizon:project:networks:editsubnet',
- args=[subnet.network_id, subnet.id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res, 'Gateway IP and IP version are inconsistent.')
-
- @test.create_stubs({api.neutron: ('subnet_modify',
- 'subnet_get',)})
- def test_subnet_update_post_invalid_nameservers(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- # invalid DNS server address
- dns_nameservers = ['192.168.0.2', 'invalid_address']
- form_data = form_data_subnet(subnet, dns_nameservers=dns_nameservers,
- allocation_pools=[])
- url = reverse('horizon:project:networks:editsubnet',
- args=[subnet.network_id, subnet.id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'dns_nameservers: Invalid IP address '
- '(value=%s)' % dns_nameservers[1])
-
- @test.create_stubs({api.neutron: ('subnet_modify',
- 'subnet_get',)})
- def test_subnet_update_post_invalid_routes_destination_only(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- # Start only host_route
- host_routes = '192.168.0.0/24'
- form_data = form_data_subnet(subnet,
- allocation_pools=[],
- host_routes=host_routes)
- url = reverse('horizon:project:networks:editsubnet',
- args=[subnet.network_id, subnet.id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'Host Routes format error: '
- 'Destination CIDR and nexthop must be specified '
- '(value=%s)' % host_routes)
-
- @test.create_stubs({api.neutron: ('subnet_modify',
- 'subnet_get',)})
- def test_subnet_update_post_invalid_routes_three_entries(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- # host_route with three entries
- host_routes = 'aaaa,bbbb,cccc'
- form_data = form_data_subnet(subnet,
- allocation_pools=[],
- host_routes=host_routes)
- url = reverse('horizon:project:networks:editsubnet',
- args=[subnet.network_id, subnet.id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'Host Routes format error: '
- 'Destination CIDR and nexthop must be specified '
- '(value=%s)' % host_routes)
-
- @test.create_stubs({api.neutron: ('subnet_modify',
- 'subnet_get',)})
- def test_subnet_update_post_invalid_routes_invalid_destination(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- # invalid destination network
- host_routes = '172.16.0.0/64,10.0.0.253'
- form_data = form_data_subnet(subnet,
- host_routes=host_routes,
- allocation_pools=[])
- url = reverse('horizon:project:networks:editsubnet',
- args=[subnet.network_id, subnet.id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'host_routes: Invalid IP address '
- '(value=%s)' % host_routes.split(',')[0])
-
- @test.create_stubs({api.neutron: ('subnet_modify',
- 'subnet_get',)})
- def test_subnet_update_post_invalid_routes_nexthop_ip_network(self):
- subnet = self.subnets.first()
- api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
- .AndReturn(subnet)
- self.mox.ReplayAll()
-
- # nexthop is not an IP address
- host_routes = '172.16.0.0/24,10.0.0.253/24'
- form_data = form_data_subnet(subnet,
- host_routes=host_routes,
- allocation_pools=[])
- url = reverse('horizon:project:networks:editsubnet',
- args=[subnet.network_id, subnet.id])
- res = self.client.post(url, form_data)
-
- self.assertContains(res,
- 'host_routes: Invalid IP address '
- '(value=%s)' % host_routes.split(',')[1])
-
- @test.create_stubs({api.neutron: ('subnet_delete',
- 'subnet_list',
- 'network_get',
- 'port_list',)})
- def test_subnet_delete(self):
- subnet = self.subnets.first()
- network_id = subnet.network_id
- api.neutron.subnet_delete(IsA(http.HttpRequest), subnet.id)
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.subnets.first()])
- api.neutron.network_get(IsA(http.HttpRequest), network_id)\
- .AndReturn(self.networks.first())
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.ports.first()])
- # Called from SubnetTable
- api.neutron.network_get(IsA(http.HttpRequest), network_id)\
- .AndReturn(self.networks.first())
- self.mox.ReplayAll()
-
- form_data = {'action': 'subnets__delete__%s' % subnet.id}
- url = reverse('horizon:project:networks:detail',
- args=[network_id])
- res = self.client.post(url, form_data)
-
- self.assertRedirectsNoFollow(res, url)
-
- @test.create_stubs({api.neutron: ('subnet_delete',
- 'subnet_list',
- 'network_get',
- 'port_list',)})
- def test_subnet_delete_excceeption(self):
- subnet = self.subnets.first()
- network_id = subnet.network_id
- api.neutron.subnet_delete(IsA(http.HttpRequest), subnet.id)\
- .AndRaise(self.exceptions.neutron)
- api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.subnets.first()])
- api.neutron.network_get(IsA(http.HttpRequest), network_id)\
- .AndReturn(self.networks.first())
- api.neutron.port_list(IsA(http.HttpRequest), network_id=network_id)\
- .AndReturn([self.ports.first()])
- # Called from SubnetTable
- api.neutron.network_get(IsA(http.HttpRequest), network_id)\
- .AndReturn(self.networks.first())
- self.mox.ReplayAll()
-
- form_data = {'action': 'subnets__delete__%s' % subnet.id}
- url = reverse('horizon:project:networks:detail',
- args=[network_id])
- res = self.client.post(url, form_data)
-
- self.assertRedirectsNoFollow(res, url)
-
-
-class NetworkPortTests(test.TestCase):
-
- @test.create_stubs({api.neutron: ('port_get',)})
- def test_port_detail(self):
- port = self.ports.first()
- api.neutron.port_get(IsA(http.HttpRequest), port.id)\
- .AndReturn(self.ports.first())
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:project:networks:ports:detail',
- args=[port.id]))
-
- self.assertTemplateUsed(res, 'project/networks/ports/detail.html')
- self.assertEqual(res.context['port'].id, port.id)
-
- @test.create_stubs({api.neutron: ('port_get',)})
- def test_port_detail_exception(self):
- port = self.ports.first()
- api.neutron.port_get(IsA(http.HttpRequest), port.id)\
- .AndRaise(self.exceptions.neutron)
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:project:networks:ports:detail',
- args=[port.id]))
-
- self.assertRedirectsNoFollow(res, INDEX_URL)
-
- @test.create_stubs({api.neutron: ('port_get',)})
- def test_port_update_get(self):
- port = self.ports.first()
- api.neutron.port_get(IsA(http.HttpRequest),
- port.id)\
- .AndReturn(port)
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:networks:editport',
- args=[port.network_id, port.id])
- res = self.client.get(url)
-
- self.assertTemplateUsed(res, 'project/networks/ports/update.html')
-
- @test.create_stubs({api.neutron: ('port_get',
- 'port_modify')})
- def test_port_update_post(self):
- port = self.ports.first()
- api.neutron.port_get(IsA(http.HttpRequest), port.id)\
- .AndReturn(port)
- api.neutron.port_modify(IsA(http.HttpRequest), port.id,
- name=port.name,
- admin_state_up=port.admin_state_up)\
- .AndReturn(port)
- self.mox.ReplayAll()
-
- form_data = {'network_id': port.network_id,
- 'port_id': port.id,
- 'name': port.name,
- 'admin_state': port.admin_state_up}
- url = reverse('horizon:project:networks:editport',
- args=[port.network_id, port.id])
- res = self.client.post(url, form_data)
-
- redir_url = reverse('horizon:project:networks:detail',
- args=[port.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
-
- @test.create_stubs({api.neutron: ('port_get',
- 'port_modify')})
- def test_port_update_post_exception(self):
- port = self.ports.first()
- api.neutron.port_get(IsA(http.HttpRequest), port.id)\
- .AndReturn(port)
- api.neutron.port_modify(IsA(http.HttpRequest), port.id,
- name=port.name,
- admin_state_up=port.admin_state_up)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- form_data = {'network_id': port.network_id,
- 'port_id': port.id,
- 'name': port.name,
- 'admin_state': port.admin_state_up}
- url = reverse('horizon:project:networks:editport',
- args=[port.network_id, port.id])
- res = self.client.post(url, form_data)
-
- redir_url = reverse('horizon:project:networks:detail',
- args=[port.network_id])
- self.assertRedirectsNoFollow(res, redir_url)
diff --git a/openstack_dashboard/dashboards/project/networks/urls.py b/openstack_dashboard/dashboards/project/networks/urls.py
deleted file mode 100644
index 5b61e258..00000000
--- a/openstack_dashboard/dashboards/project/networks/urls.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.defaults import include
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.networks.ports \
- import urls as port_urls
-from openstack_dashboard.dashboards.project.networks.ports.views \
- import UpdateView as EditPortView
-from openstack_dashboard.dashboards.project.networks.subnets \
- import urls as subnet_urls
-from openstack_dashboard.dashboards.project.networks.subnets.views \
- import CreateView as AddSubnetView
-from openstack_dashboard.dashboards.project.networks.subnets.views \
- import UpdateView as EditSubnetView
-from openstack_dashboard.dashboards.project.networks.views import CreateView
-from openstack_dashboard.dashboards.project.networks.views import DetailView
-from openstack_dashboard.dashboards.project.networks.views import IndexView
-from openstack_dashboard.dashboards.project.networks.views import UpdateView
-
-
-NETWORKS = r'^(?P<network_id>[^/]+)/%s$'
-
-
-urlpatterns = patterns('',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^create$', CreateView.as_view(), name='create'),
- url(NETWORKS % 'detail', DetailView.as_view(), name='detail'),
- url(NETWORKS % 'update', UpdateView.as_view(), name='update'),
- url(NETWORKS % 'subnets/create', AddSubnetView.as_view(),
- name='addsubnet'),
- url(r'^(?P<network_id>[^/]+)/subnets/(?P<subnet_id>[^/]+)/update$',
- EditSubnetView.as_view(), name='editsubnet'),
- url(r'^(?P<network_id>[^/]+)/ports/(?P<port_id>[^/]+)/update$',
- EditPortView.as_view(), name='editport'),
- url(r'^subnets/', include(subnet_urls, namespace='subnets')),
- url(r'^ports/', include(port_urls, namespace='ports')))
diff --git a/openstack_dashboard/dashboards/project/networks/views.py b/openstack_dashboard/dashboards/project/networks/views.py
deleted file mode 100644
index 1df1cf7b..00000000
--- a/openstack_dashboard/dashboards/project/networks/views.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing Neutron Networks.
-"""
-import logging
-
-from django.core.urlresolvers import reverse_lazy
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-from horizon import workflows
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.project.networks.forms import UpdateNetwork
-from openstack_dashboard.dashboards.project.networks.ports.tables \
- import PortsTable
-from openstack_dashboard.dashboards.project.networks.subnets.tables \
- import SubnetsTable
-from openstack_dashboard.dashboards.project.networks.tables \
- import NetworksTable
-from openstack_dashboard.dashboards.project.networks.workflows \
- import CreateNetwork
-
-
-LOG = logging.getLogger(__name__)
-
-
-class IndexView(tables.DataTableView):
- table_class = NetworksTable
- template_name = 'project/networks/index.html'
-
- def get_data(self):
- try:
- tenant_id = self.request.user.tenant_id
- networks = api.neutron.network_list_for_tenant(self.request,
- tenant_id)
- except:
- networks = []
- msg = _('Network list can not be retrieved.')
- exceptions.handle(self.request, msg)
- for n in networks:
- n.set_id_as_name_if_empty()
- return networks
-
-
-class CreateView(workflows.WorkflowView):
- workflow_class = CreateNetwork
-
- def get_initial(self):
- pass
-
-
-class UpdateView(forms.ModalFormView):
- form_class = UpdateNetwork
- template_name = 'project/networks/update.html'
- context_object_name = 'network'
- success_url = reverse_lazy("horizon:project:networks:index")
-
- def get_context_data(self, **kwargs):
- context = super(UpdateView, self).get_context_data(**kwargs)
- context["network_id"] = self.kwargs['network_id']
- return context
-
- def _get_object(self, *args, **kwargs):
- if not hasattr(self, "_object"):
- network_id = self.kwargs['network_id']
- try:
- self._object = api.neutron.network_get(self.request,
- network_id)
- except:
- redirect = self.success_url
- msg = _('Unable to retrieve network details.')
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_initial(self):
- network = self._get_object()
- return {'network_id': network['id'],
- 'tenant_id': network['tenant_id'],
- 'name': network['name'],
- 'admin_state': network['admin_state_up']}
-
-
-class DetailView(tables.MultiTableView):
- table_classes = (SubnetsTable, PortsTable)
- template_name = 'project/networks/detail.html'
- failure_url = reverse_lazy('horizon:project:networks:index')
-
- def get_subnets_data(self):
- try:
- network = self._get_data()
- subnets = api.neutron.subnet_list(self.request,
- network_id=network.id)
- except:
- subnets = []
- msg = _('Subnet list can not be retrieved.')
- exceptions.handle(self.request, msg)
- for s in subnets:
- s.set_id_as_name_if_empty()
- return subnets
-
- def get_ports_data(self):
- try:
- network_id = self.kwargs['network_id']
- ports = api.neutron.port_list(self.request, network_id=network_id)
- except:
- ports = []
- msg = _('Port list can not be retrieved.')
- exceptions.handle(self.request, msg)
- for p in ports:
- p.set_id_as_name_if_empty()
- return ports
-
- def _get_data(self):
- if not hasattr(self, "_network"):
- try:
- network_id = self.kwargs['network_id']
- network = api.neutron.network_get(self.request, network_id)
- network.set_id_as_name_if_empty(length=0)
- except:
- msg = _('Unable to retrieve details for network "%s".') \
- % (network_id)
- exceptions.handle(self.request, msg, redirect=self.failure_url)
- self._network = network
- return self._network
-
- def get_context_data(self, **kwargs):
- context = super(DetailView, self).get_context_data(**kwargs)
- context["network"] = self._get_data()
- return context
diff --git a/openstack_dashboard/dashboards/project/networks/workflows.py b/openstack_dashboard/dashboards/project/networks/workflows.py
deleted file mode 100644
index 4ad02979..00000000
--- a/openstack_dashboard/dashboards/project/networks/workflows.py
+++ /dev/null
@@ -1,370 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-import logging
-import netaddr
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-from horizon.utils import fields
-from horizon import workflows
-
-from openstack_dashboard import api
-
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateNetworkInfoAction(workflows.Action):
- net_name = forms.CharField(max_length=255,
- label=_("Network Name"),
- help_text=_("Network Name. This field is "
- "optional."),
- required=False)
- admin_state = forms.BooleanField(label=_("Admin State"),
- initial=True, required=False)
-
- class Meta:
- name = _("Network")
- help_text = _("From here you can create a new network.\n"
- "In addition a subnet associated with the network "
- "can be created in the next panel.")
-
-
-class CreateNetworkInfo(workflows.Step):
- action_class = CreateNetworkInfoAction
- contributes = ("net_name", "admin_state")
-
-
-class CreateSubnetInfoAction(workflows.Action):
- with_subnet = forms.BooleanField(label=_("Create Subnet"),
- initial=True, required=False)
- subnet_name = forms.CharField(max_length=255,
- label=_("Subnet Name"),
- help_text=_("Subnet Name. This field is "
- "optional."),
- required=False)
- cidr = fields.IPField(label=_("Network Address"),
- required=False,
- initial="",
- help_text=_("Network address in CIDR format "
- "(e.g. 192.168.0.0/24)"),
- version=fields.IPv4 | fields.IPv6,
- mask=True)
- ip_version = forms.ChoiceField(choices=[(4, 'IPv4'), (6, 'IPv6')],
- label=_("IP Version"))
- gateway_ip = fields.IPField(
- label=_("Gateway IP (optional)"),
- required=False,
- initial="",
- help_text=_("IP address of Gateway (e.g. 192.168.0.254) "
- "The default value is the first IP of the "
- "network address (e.g. 192.168.0.1 for "
- "192.168.0.0/24). "
- "If you use the default, leave blank. "
- "If you want to use no gateway, "
- "check 'Disable Gateway' below."),
- version=fields.IPv4 | fields.IPv6,
- mask=False)
- no_gateway = forms.BooleanField(label=_("Disable Gateway"),
- initial=False, required=False)
-
- class Meta:
- name = _("Subnet")
- help_text = _('You can create a subnet associated with the new '
- 'network, in which case "Network Address" must be '
- 'specified. If you wish to create a network WITHOUT a '
- 'subnet, uncheck the "Create Subnet" checkbox.')
-
- def _check_subnet_data(self, cleaned_data, is_create=True):
- cidr = cleaned_data.get('cidr')
- ip_version = int(cleaned_data.get('ip_version'))
- gateway_ip = cleaned_data.get('gateway_ip')
- no_gateway = cleaned_data.get('no_gateway')
- if not cidr:
- msg = _('Specify "Network Address" or '
- 'clear "Create Subnet" checkbox.')
- raise forms.ValidationError(msg)
- if cidr:
- subnet = netaddr.IPNetwork(cidr)
- if subnet.version != ip_version:
- msg = _('Network Address and IP version are inconsistent.')
- raise forms.ValidationError(msg)
- if (ip_version == 4 and subnet.prefixlen == 32) or \
- (ip_version == 6 and subnet.prefixlen == 128):
- msg = _("The subnet in the Network Address is too small (/%s)."
- % subnet.prefixlen)
- raise forms.ValidationError(msg)
- if not no_gateway and gateway_ip:
- if netaddr.IPAddress(gateway_ip).version is not ip_version:
- msg = _('Gateway IP and IP version are inconsistent.')
- raise forms.ValidationError(msg)
- if not is_create and not no_gateway and not gateway_ip:
- msg = _('Specify IP address of gateway or '
- 'check "Disable Gateway".')
- raise forms.ValidationError(msg)
-
- def clean(self):
- cleaned_data = super(CreateSubnetInfoAction, self).clean()
- with_subnet = cleaned_data.get('with_subnet')
- if not with_subnet:
- return cleaned_data
- self._check_subnet_data(cleaned_data)
- return cleaned_data
-
-
-class CreateSubnetInfo(workflows.Step):
- action_class = CreateSubnetInfoAction
- contributes = ("with_subnet", "subnet_name", "cidr",
- "ip_version", "gateway_ip", "no_gateway")
-
-
-class CreateSubnetDetailAction(workflows.Action):
- enable_dhcp = forms.BooleanField(label=_("Enable DHCP"),
- initial=True, required=False)
- allocation_pools = forms.CharField(
- widget=forms.Textarea(),
- label=_("Allocation Pools"),
- help_text=_("IP address allocation pools. Each entry is "
- "&lt;start_ip_address&gt;,&lt;end_ip_address&gt; "
- "(e.g., 192.168.1.100,192.168.1.120) "
- "and one entry per line."),
- required=False)
- dns_nameservers = forms.CharField(
- widget=forms.widgets.Textarea(),
- label=_("DNS Name Servers"),
- help_text=_("IP address list of DNS name servers for this subnet. "
- "One entry per line."),
- required=False)
- host_routes = forms.CharField(
- widget=forms.widgets.Textarea(),
- label=_("Host Routes"),
- help_text=_("Additional routes announced to the hosts. "
- "Each entry is &lt;destination_cidr&gt;,&lt;nexthop&gt; "
- "(e.g., 192.168.200.0/24,10.56.1.254)"
- "and one entry per line."),
- required=False)
-
- class Meta:
- name = _("Subnet Detail")
- help_text = _('You can specify additional attributes for the subnet.')
-
- def _convert_ip_address(self, ip, field_name):
- try:
- return netaddr.IPAddress(ip)
- except (netaddr.AddrFormatError, ValueError):
- msg = _('%(field_name)s: Invalid IP address '
- '(value=%(ip)s)') % locals()
- raise forms.ValidationError(msg)
-
- def _convert_ip_network(self, network, field_name):
- try:
- return netaddr.IPNetwork(network)
- except (netaddr.AddrFormatError, ValueError):
- msg = _('%(field_name)s: Invalid IP address '
- '(value=%(network)s)') % locals()
- raise forms.ValidationError(msg)
-
- def _check_allocation_pools(self, allocation_pools):
- for p in allocation_pools.split('\n'):
- p = p.strip()
- if not p:
- continue
- pool = p.split(',')
- if len(pool) != 2:
- msg = _('Start and end addresses must be specified '
- '(value=%s)') % p
- raise forms.ValidationError(msg)
- start, end = [self._convert_ip_address(ip, "allocation_pools")
- for ip in pool]
- if start > end:
- msg = _('Start address is larger than end address '
- '(value=%s)') % p
- raise forms.ValidationError(msg)
-
- def _check_dns_nameservers(self, dns_nameservers):
- for ns in dns_nameservers.split('\n'):
- ns = ns.strip()
- if not ns:
- continue
- self._convert_ip_address(ns, "dns_nameservers")
-
- def _check_host_routes(self, host_routes):
- for r in host_routes.split('\n'):
- r = r.strip()
- if not r:
- continue
- route = r.split(',')
- if len(route) != 2:
- msg = _('Host Routes format error: '
- 'Destination CIDR and nexthop must be specified '
- '(value=%s)') % r
- raise forms.ValidationError(msg)
- self._convert_ip_network(route[0], "host_routes")
- self._convert_ip_address(route[1], "host_routes")
-
- def clean(self):
- cleaned_data = super(CreateSubnetDetailAction, self).clean()
- self._check_allocation_pools(cleaned_data.get('allocation_pools'))
- self._check_host_routes(cleaned_data.get('host_routes'))
- self._check_dns_nameservers(cleaned_data.get('dns_nameservers'))
- return cleaned_data
-
-
-class CreateSubnetDetail(workflows.Step):
- action_class = CreateSubnetDetailAction
- contributes = ("enable_dhcp", "allocation_pools",
- "dns_nameservers", "host_routes")
-
-
-class CreateNetwork(workflows.Workflow):
- slug = "create_network"
- name = _("Create Network")
- finalize_button_name = _("Create")
- success_message = _('Created network "%s".')
- failure_message = _('Unable to create network "%s".')
- default_steps = (CreateNetworkInfo,
- CreateSubnetInfo,
- CreateSubnetDetail)
-
- def get_success_url(self):
- return reverse("horizon:project:networks:index")
-
- def get_failure_url(self):
- return reverse("horizon:project:networks:index")
-
- def format_status_message(self, message):
- name = self.context.get('net_name') or self.context.get('net_id', '')
- return message % name
-
- def _create_network(self, request, data):
- try:
- params = {'name': data['net_name'],
- 'admin_state_up': data['admin_state']}
- network = api.neutron.network_create(request, **params)
- network.set_id_as_name_if_empty()
- self.context['net_id'] = network.id
- msg = _('Network "%s" was successfully created.') % network.name
- LOG.debug(msg)
- return network
- except Exception as e:
- msg = (_('Failed to create network "%(network)s": %(reason)s') %
- {"network": data['net_name'], "reason": e})
- LOG.info(msg)
- redirect = self.get_failure_url()
- exceptions.handle(request, msg, redirect=redirect)
- return False
-
- def _setup_subnet_parameters(self, params, data, is_create=True):
- """Setup subnet parameters
-
- This methods setups subnet parameters which are available
- in both create and update.
- """
- is_update = not is_create
- params['enable_dhcp'] = data['enable_dhcp']
- if is_create and data['allocation_pools']:
- pools = [dict(zip(['start', 'end'], pool.strip().split(',')))
- for pool in data['allocation_pools'].split('\n')
- if pool.strip()]
- params['allocation_pools'] = pools
- if data['host_routes'] or is_update:
- routes = [dict(zip(['destination', 'nexthop'],
- route.strip().split(',')))
- for route in data['host_routes'].split('\n')
- if route.strip()]
- params['host_routes'] = routes
- if data['dns_nameservers'] or is_update:
- nameservers = [ns.strip()
- for ns in data['dns_nameservers'].split('\n')
- if ns.strip()]
- params['dns_nameservers'] = nameservers
-
- def _create_subnet(self, request, data, network=None, tenant_id=None,
- no_redirect=False):
- if network:
- network_id = network.id
- network_name = network.name
- else:
- network_id = self.context.get('network_id')
- network_name = self.context.get('network_name')
- try:
- params = {'network_id': network_id,
- 'name': data['subnet_name'],
- 'cidr': data['cidr'],
- 'ip_version': int(data['ip_version'])}
- if tenant_id:
- params['tenant_id'] = tenant_id
- if data['no_gateway']:
- params['gateway_ip'] = None
- elif data['gateway_ip']:
- params['gateway_ip'] = data['gateway_ip']
-
- self._setup_subnet_parameters(params, data)
-
- subnet = api.neutron.subnet_create(request, **params)
- self.context['subnet_id'] = subnet.id
- msg = _('Subnet "%s" was successfully created.') % data['cidr']
- LOG.debug(msg)
- return subnet
- except Exception as e:
- msg = _('Failed to create subnet "%(sub)s" for network "%(net)s": '
- ' %(reason)s')
- if no_redirect:
- redirect = None
- else:
- redirect = self.get_failure_url()
- exceptions.handle(request,
- msg % {"sub": data['cidr'], "net": network_name,
- "reason": e},
- redirect=redirect)
- return False
-
- def _delete_network(self, request, network):
- """Delete the created network when subnet creation failed"""
- try:
- api.neutron.network_delete(request, network.id)
- msg = _('Delete the created network "%s" '
- 'due to subnet creation failure.') % network.name
- LOG.debug(msg)
- redirect = self.get_failure_url()
- messages.info(request, msg)
- raise exceptions.Http302(redirect)
- #return exceptions.RecoverableError
- except:
- msg = _('Failed to delete network "%s"') % network.name
- LOG.info(msg)
- redirect = self.get_failure_url()
- exceptions.handle(request, msg, redirect=redirect)
-
- def handle(self, request, data):
- network = self._create_network(request, data)
- if not network:
- return False
- # If we do not need to create a subnet, return here.
- if not data['with_subnet']:
- return True
- subnet = self._create_subnet(request, data, network, no_redirect=True)
- if subnet:
- return True
- else:
- self._delete_network(request, network)
- return False
diff --git a/openstack_dashboard/dashboards/project/overview/__init__.py b/openstack_dashboard/dashboards/project/overview/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/overview/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/overview/panel.py b/openstack_dashboard/dashboards/project/overview/panel.py
deleted file mode 100644
index 7ec447b4..00000000
--- a/openstack_dashboard/dashboards/project/overview/panel.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.project import dashboard
-
-
-class Overview(horizon.Panel):
- name = _("Overview")
- slug = 'overview'
-
-
-dashboard.Project.register(Overview)
diff --git a/openstack_dashboard/dashboards/project/overview/templates/overview/usage.csv b/openstack_dashboard/dashboards/project/overview/templates/overview/usage.csv
deleted file mode 100644
index b2768b50..00000000
--- a/openstack_dashboard/dashboards/project/overview/templates/overview/usage.csv
+++ /dev/null
@@ -1,7 +0,0 @@
-{% load i18n %}{% trans "Usage Report For Period" %}:,{{ usage.start|date:"b. d Y" }},{{ usage.end|date:"b. d Y" }}
-{% trans "Project ID" %}:,{{ usage.project_id }}
-{% trans "Total Active VCPUs" %}:,{{ usage.summary.instances }}
-{% trans "CPU-HRs Used" %}:,{{ usage.summary.vcpu_hours|floatformat:2 }}
-{% trans "Total Active Ram (MB)" %}:,{{ usage.summary.memory_mb }}
-{% trans "Total Disk Size" %}:,{{ usage.summary.local_gb }}
-{% trans "Total Disk Usage" %}:,{{ usage.summary.disk_gb_hours|floatformat:2 }}
diff --git a/openstack_dashboard/dashboards/project/overview/templates/overview/usage.html b/openstack_dashboard/dashboards/project/overview/templates/overview/usage.html
deleted file mode 100644
index 3651499a..00000000
--- a/openstack_dashboard/dashboards/project/overview/templates/overview/usage.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Instance Overview" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Overview") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "horizon/common/_limit_summary.html" %}
- {% include "horizon/common/_usage_summary.html" %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/overview/tests.py b/openstack_dashboard/dashboards/project/overview/tests.py
deleted file mode 100644
index 47da3e50..00000000
--- a/openstack_dashboard/dashboards/project/overview/tests.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import datetime
-
-from django.core.urlresolvers import reverse
-from django import http
-from django.utils import timezone
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-from openstack_dashboard import usage
-
-
-INDEX_URL = reverse('horizon:project:overview:index')
-
-
-class UsageViewTests(test.TestCase):
- def test_usage(self):
- now = timezone.now()
- usage_obj = api.nova.NovaUsage(self.usages.first())
- self.mox.StubOutWithMock(api.nova, 'usage_get')
- self.mox.StubOutWithMock(api.nova, 'tenant_absolute_limits')
- api.nova.usage_get(IsA(http.HttpRequest), self.tenant.id,
- datetime.datetime(now.year,
- now.month,
- now.day, 0, 0, 0, 0),
- datetime.datetime(now.year,
- now.month,
- now.day, 23, 59, 59, 0)) \
- .AndReturn(usage_obj)
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\
- .AndReturn(self.limits['absolute'])
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:project:overview:index'))
- self.assertTemplateUsed(res, 'project/overview/usage.html')
- self.assertTrue(isinstance(res.context['usage'], usage.ProjectUsage))
- self.assertContains(res, 'form-horizontal')
-
- def test_unauthorized(self):
- exc = self.exceptions.nova_unauthorized
- now = timezone.now()
- self.mox.StubOutWithMock(api.nova, 'usage_get')
- self.mox.StubOutWithMock(api.nova, 'tenant_absolute_limits')
- api.nova.usage_get(IsA(http.HttpRequest), self.tenant.id,
- datetime.datetime(now.year,
- now.month,
- now.day, 0, 0, 0, 0),
- datetime.datetime(now.year,
- now.month,
- now.day, 23, 59, 59, 0)) \
- .AndRaise(exc)
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\
- .AndReturn(self.limits['absolute'])
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:overview:index')
- res = self.client.get(url)
- self.assertTemplateUsed(res, 'project/overview/usage.html')
- self.assertMessageCount(res, error=1)
- self.assertContains(res, 'Unauthorized:')
-
- def test_usage_csv(self):
- now = timezone.now()
- usage_obj = api.nova.NovaUsage(self.usages.first())
- self.mox.StubOutWithMock(api.nova, 'usage_get')
- self.mox.StubOutWithMock(api.nova, 'tenant_absolute_limits')
- start = datetime.datetime(now.year, now.month, now.day, 0, 0, 0, 0)
- end = datetime.datetime(now.year, now.month, now.day, 23, 59, 59, 0)
- api.nova.usage_get(IsA(http.HttpRequest),
- self.tenant.id,
- start, end).AndReturn(usage_obj)
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\
- .AndReturn(self.limits['absolute'])
-
- self.mox.ReplayAll()
- res = self.client.get(reverse('horizon:project:overview:index') +
- "?format=csv")
- self.assertTemplateUsed(res, 'project/overview/usage.csv')
- self.assertTrue(isinstance(res.context['usage'], usage.ProjectUsage))
-
- def test_usage_exception_usage(self):
- now = timezone.now()
- self.mox.StubOutWithMock(api.nova, 'usage_get')
- self.mox.StubOutWithMock(api.nova, 'tenant_absolute_limits')
- start = datetime.datetime(now.year, now.month, now.day, 0, 0, 0, 0)
- end = datetime.datetime(now.year, now.month, now.day, 23, 59, 59, 0)
- api.nova.usage_get(IsA(http.HttpRequest),
- self.tenant.id,
- start, end).AndRaise(self.exceptions.nova)
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\
- .AndReturn(self.limits['absolute'])
-
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:project:overview:index'))
- self.assertTemplateUsed(res, 'project/overview/usage.html')
- self.assertEqual(res.context['usage'].usage_list, [])
-
- def test_usage_exception_quota(self):
- now = timezone.now()
- usage_obj = api.nova.NovaUsage(self.usages.first())
- self.mox.StubOutWithMock(api.nova, 'usage_get')
- self.mox.StubOutWithMock(api.nova, 'tenant_absolute_limits')
- start = datetime.datetime(now.year, now.month, now.day, 0, 0, 0, 0)
- end = datetime.datetime(now.year, now.month, now.day, 23, 59, 59, 0)
- api.nova.usage_get(IsA(http.HttpRequest),
- self.tenant.id,
- start, end).AndReturn(usage_obj)
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\
- .AndRaise(self.exceptions.nova)
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:project:overview:index'))
- self.assertTemplateUsed(res, 'project/overview/usage.html')
- self.assertEqual(res.context['usage'].quotas, {})
-
- def test_usage_default_tenant(self):
- now = timezone.now()
- usage_obj = api.nova.NovaUsage(self.usages.first())
- self.mox.StubOutWithMock(api.nova, 'usage_get')
- self.mox.StubOutWithMock(api.nova, 'tenant_absolute_limits')
- start = datetime.datetime(now.year, now.month, now.day, 0, 0, 0, 0)
- end = datetime.datetime(now.year, now.month, now.day, 23, 59, 59, 0)
- api.nova.usage_get(IsA(http.HttpRequest),
- self.tenant.id,
- start, end).AndReturn(usage_obj)
- api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\
- .AndReturn(self.limits['absolute'])
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:project:overview:index'))
- self.assertTemplateUsed(res, 'project/overview/usage.html')
- self.assertTrue(isinstance(res.context['usage'], usage.ProjectUsage))
diff --git a/openstack_dashboard/dashboards/project/overview/urls.py b/openstack_dashboard/dashboards/project/overview/urls.py
deleted file mode 100644
index abd7f25b..00000000
--- a/openstack_dashboard/dashboards/project/overview/urls.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.overview.views \
- import ProjectOverview
-from openstack_dashboard.dashboards.project.overview.views import WarningView
-
-
-urlpatterns = patterns('openstack_dashboard.dashboards.project.overview.views',
- url(r'^$', ProjectOverview.as_view(), name='index'),
- url(r'^warning$', WarningView.as_view(), name='warning'),
-)
diff --git a/openstack_dashboard/dashboards/project/overview/views.py b/openstack_dashboard/dashboards/project/overview/views.py
deleted file mode 100644
index 1b427b3c..00000000
--- a/openstack_dashboard/dashboards/project/overview/views.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-from django.template.defaultfilters import capfirst
-from django.template.defaultfilters import floatformat
-from django.utils.translation import ugettext as _
-from django.views.generic import TemplateView
-
-from openstack_dashboard import usage
-from openstack_dashboard.usage.base import BaseCsvResponse
-
-
-class ProjectUsageCsvRenderer(BaseCsvResponse):
-
- columns = [_("Instance Name"), _("VCPUs"), _("Ram (MB)"),
- _("Disk (GB)"), _("Usage (Hours)"),
- _("Uptime(Seconds)"), _("State")]
-
- def get_row_data(self):
-
- for inst in self.context['usage'].get_instances():
- yield (inst['name'],
- inst['vcpus'],
- inst['memory_mb'],
- inst['local_gb'],
- floatformat(inst['hours'], 2),
- inst['uptime'],
- capfirst(inst['state']))
-
-
-class ProjectOverview(usage.UsageView):
- table_class = usage.ProjectUsageTable
- usage_class = usage.ProjectUsage
- template_name = 'project/overview/usage.html'
- csv_response_class = ProjectUsageCsvRenderer
-
- def get_data(self):
- super(ProjectOverview, self).get_data()
- return self.usage.get_instances()
-
-
-class WarningView(TemplateView):
- template_name = "project/_warning.html"
diff --git a/openstack_dashboard/dashboards/project/routers/__init__.py b/openstack_dashboard/dashboards/project/routers/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/routers/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/routers/forms.py b/openstack_dashboard/dashboards/project/routers/forms.py
deleted file mode 100644
index 77e53a0c..00000000
--- a/openstack_dashboard/dashboards/project/routers/forms.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, Inc.
-# All rights reserved.
-
-"""
-Views for managing Neutron Routers.
-"""
-import logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-from openstack_dashboard import api
-
-LOG = logging.getLogger(__name__)
-
-
-class CreateForm(forms.SelfHandlingForm):
- name = forms.CharField(max_length="255", label=_("Router Name"))
- failure_url = 'horizon:project:routers:index'
-
- def __init__(self, request, *args, **kwargs):
- super(CreateForm, self).__init__(request, *args, **kwargs)
-
- def handle(self, request, data):
- try:
- router = api.neutron.router_create(request,
- name=data['name'])
- message = _('Router %s was successfully created.') % data['name']
- messages.success(request, message)
- return router
- except:
- msg = _('Failed to create router "%s".') % data['name']
- LOG.info(msg)
- redirect = reverse(self.failure_url)
- exceptions.handle(request, msg, redirect=redirect)
- return False
diff --git a/openstack_dashboard/dashboards/project/routers/panel.py b/openstack_dashboard/dashboards/project/routers/panel.py
deleted file mode 100644
index fbaf831e..00000000
--- a/openstack_dashboard/dashboards/project/routers/panel.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.project import dashboard
-
-
-class Routers(horizon.Panel):
- name = _("Routers")
- slug = 'routers'
- permissions = ('openstack.services.network',)
-
-dashboard.Project.register(Routers)
diff --git a/openstack_dashboard/dashboards/project/routers/ports/__init__.py b/openstack_dashboard/dashboards/project/routers/ports/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/routers/ports/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/routers/ports/forms.py b/openstack_dashboard/dashboards/project/routers/ports/forms.py
deleted file mode 100644
index 51302703..00000000
--- a/openstack_dashboard/dashboards/project/routers/ports/forms.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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 logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-from horizon.utils import fields
-from openstack_dashboard import api
-
-LOG = logging.getLogger(__name__)
-
-
-class AddInterface(forms.SelfHandlingForm):
- subnet_id = forms.ChoiceField(label=_("Subnet"))
- ip_address = fields.IPField(
- label=_("IP Address (optional)"), required=False, initial="",
- help_text=_("You can specify an IP address of the interface "
- "created if you want (e.g. 192.168.0.254)."),
- version=fields.IPv4 | fields.IPv6, mask=False)
- router_name = forms.CharField(label=_("Router Name"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- router_id = forms.CharField(label=_("Router ID"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- failure_url = 'horizon:project:routers:detail'
-
- def __init__(self, request, *args, **kwargs):
- super(AddInterface, self).__init__(request, *args, **kwargs)
- c = self.populate_subnet_id_choices(request)
- self.fields['subnet_id'].choices = c
-
- def populate_subnet_id_choices(self, request):
- tenant_id = self.request.user.tenant_id
- networks = []
- try:
- networks = api.neutron.network_list_for_tenant(request, tenant_id)
- except Exception as e:
- msg = _('Failed to get network list %s') % e.message
- LOG.info(msg)
- messages.error(request, msg)
- redirect = reverse(self.failure_url,
- args=[request.REQUEST['router_id']])
- exceptions.handle(request, msg, redirect=redirect)
- return
-
- choices = []
- for n in networks:
- net_name = n.name + ': ' if n.name else ''
- choices += [(subnet.id,
- '%s%s (%s)' % (net_name, subnet.cidr,
- subnet.name or subnet.id))
- for subnet in n['subnets']]
- if choices:
- choices.insert(0, ("", _("Select Subnet")))
- else:
- choices.insert(0, ("", _("No subnets available.")))
- return choices
-
- def handle(self, request, data):
- if data['ip_address']:
- port = self._add_interface_by_port(request, data)
- else:
- port = self._add_interface_by_subnet(request, data)
- msg = _('Interface added')
- if port:
- msg += ' ' + port.fixed_ips[0]['ip_address']
- LOG.debug(msg)
- messages.success(request, msg)
- return True
-
- def _add_interface_by_subnet(self, request, data):
- router_id = data['router_id']
- try:
- router_inf = api.neutron.router_add_interface(
- request, router_id, subnet_id=data['subnet_id'])
- except Exception as e:
- self._handle_error(request, router_id, e)
- try:
- port = api.neutron.port_get(request, router_inf['port_id'])
- except:
- # Ignore an error when port_get() since it is just
- # to get an IP address for the interface.
- port = None
- return port
-
- def _add_interface_by_port(self, request, data):
- router_id = data['router_id']
- subnet_id = data['subnet_id']
- try:
- subnet = api.neutron.subnet_get(request, subnet_id)
- except:
- msg = _('Unable to get subnet "%s"') % subnet_id
- self._handle_error(request, router_id, msg)
- try:
- ip_address = data['ip_address']
- body = {'network_id': subnet.network_id,
- 'fixed_ips': [{'subnet_id': subnet.id,
- 'ip_address': ip_address}]}
- port = api.neutron.port_create(request, **body)
- except Exception as e:
- self._handle_error(request, router_id, e)
- try:
- api.neutron.router_add_interface(request, router_id,
- port_id=port.id)
- except Exception as e:
- self._delete_port(request, port)
- self._handle_error(request, router_id, e)
- return port
-
- def _handle_error(self, request, router_id, reason):
- msg = _('Failed to add_interface: %s') % reason
- LOG.info(msg)
- redirect = reverse(self.failure_url, args=[router_id])
- exceptions.handle(request, msg, redirect=redirect)
-
- def _delete_port(self, request, port):
- try:
- api.neutron.port_delete(request, port.id)
- except:
- msg = _('Failed to delete port %s') % port.id
- LOG.info(msg)
- exceptions.handle(request, msg)
-
-
-class SetGatewayForm(forms.SelfHandlingForm):
- network_id = forms.ChoiceField(label=_("External Network"))
- router_name = forms.CharField(label=_("Router Name"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- router_id = forms.CharField(label=_("Router ID"),
- widget=forms.TextInput(
- attrs={'readonly': 'readonly'}))
- failure_url = 'horizon:project:routers:index'
-
- def __init__(self, request, *args, **kwargs):
- super(SetGatewayForm, self).__init__(request, *args, **kwargs)
- c = self.populate_network_id_choices(request)
- self.fields['network_id'].choices = c
-
- def populate_network_id_choices(self, request):
- search_opts = {'router:external': True}
- try:
- networks = api.neutron.network_list(request, **search_opts)
- except Exception as e:
- msg = _('Failed to get network list %s') % e.message
- LOG.info(msg)
- messages.error(request, msg)
- redirect = reverse(self.failure_url)
- exceptions.handle(request, msg, redirect=redirect)
- return
- choices = [(network.id, network.name or network.id)
- for network in networks]
- if choices:
- choices.insert(0, ("", _("Select network")))
- else:
- choices.insert(0, ("", _("No networks available.")))
- return choices
-
- def handle(self, request, data):
- try:
- api.neutron.router_add_gateway(request,
- data['router_id'],
- data['network_id'])
- msg = _('Gateway interface is added')
- LOG.debug(msg)
- messages.success(request, msg)
- return True
- except Exception as e:
- msg = _('Failed to set gateway %s') % e.message
- LOG.info(msg)
- redirect = reverse(self.failure_url)
- exceptions.handle(request, msg, redirect=redirect)
diff --git a/openstack_dashboard/dashboards/project/routers/ports/tables.py b/openstack_dashboard/dashboards/project/routers/ports/tables.py
deleted file mode 100644
index 01576373..00000000
--- a/openstack_dashboard/dashboards/project/routers/ports/tables.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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 logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.networks.ports.tables import\
- get_fixed_ips
-
-LOG = logging.getLogger(__name__)
-
-
-def get_device_owner(port):
- if port['device_owner'] == 'network:router_gateway':
- return _('External Gateway')
- elif port['device_owner'] == 'network:router_interface':
- return _('Internal Interface')
- else:
- return ' '
-
-
-class AddInterface(tables.LinkAction):
- name = "create"
- verbose_name = _("Add Interface")
- url = "horizon:project:routers:addinterface"
- classes = ("ajax-modal", "btn-create")
-
- def get_link_url(self, datum=None):
- router_id = self.table.kwargs['router_id']
- return reverse(self.url, args=(router_id,))
-
-
-class RemoveInterface(tables.DeleteAction):
- data_type_singular = _("Interface")
- data_type_plural = _("Interfaces")
- failure_url = 'horizon:project:routers:detail'
-
- def delete(self, request, obj_id):
- try:
- router_id = self.table.kwargs['router_id']
- port = api.neutron.port_get(request, obj_id)
- if port['device_owner'] == 'network:router_gateway':
- api.neutron.router_remove_gateway(request, router_id)
- else:
- api.neutron.router_remove_interface(request,
- router_id,
- port_id=obj_id)
- except:
- msg = _('Failed to delete interface %s') % obj_id
- LOG.info(msg)
- router_id = self.table.kwargs['router_id']
- redirect = reverse(self.failure_url,
- args=[router_id])
- exceptions.handle(request, msg, redirect=redirect)
-
- def allowed(self, request, datum=None):
- if datum and datum['device_owner'] == 'network:router_gateway':
- return False
- return True
-
-
-class PortsTable(tables.DataTable):
- name = tables.Column("name",
- verbose_name=_("Name"),
- link="horizon:project:networks:ports:detail")
- fixed_ips = tables.Column(get_fixed_ips, verbose_name=_("Fixed IPs"))
- status = tables.Column("status", verbose_name=_("Status"))
- device_owner = tables.Column(get_device_owner,
- verbose_name=_("Type"))
- admin_state = tables.Column("admin_state",
- verbose_name=_("Admin State"))
-
- def get_object_display(self, port):
- return port.id
-
- class Meta:
- name = "interfaces"
- verbose_name = _("Interfaces")
- table_actions = (AddInterface, RemoveInterface)
- row_actions = (RemoveInterface, )
diff --git a/openstack_dashboard/dashboards/project/routers/ports/tabs.py b/openstack_dashboard/dashboards/project/routers/ports/tabs.py
deleted file mode 100644
index 476ab5d2..00000000
--- a/openstack_dashboard/dashboards/project/routers/ports/tabs.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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 logging
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-from openstack_dashboard import api
-
-LOG = logging.getLogger(__name__)
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "overview"
- template_name = "project/networks/ports/_detail_overview.html"
- failure_url = 'horizon:project:routers:index'
-
- def get_context_data(self, request):
- port_id = self.tab_group.kwargs['port_id']
- try:
- port = api.neutron.port_get(self.request, port_id)
- except:
- redirect = reverse(self.failure_url)
- msg = _('Unable to retrieve port details.')
- exceptions.handle(request, msg, redirect=redirect)
- return {'port': port}
-
-
-class PortDetailTabs(tabs.TabGroup):
- slug = "port_details"
- tabs = (OverviewTab,)
diff --git a/openstack_dashboard/dashboards/project/routers/ports/urls.py b/openstack_dashboard/dashboards/project/routers/ports/urls.py
deleted file mode 100644
index 06a2c839..00000000
--- a/openstack_dashboard/dashboards/project/routers/ports/urls.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.routers.ports.views \
- import DetailView
-
-PORTS = r'^(?P<port_id>[^/]+)/%s$'
-
-urlpatterns = patterns('horizon.dashboards.project.networks.ports.views',
- url(PORTS % 'detail', DetailView.as_view(), name='detail'))
diff --git a/openstack_dashboard/dashboards/project/routers/ports/views.py b/openstack_dashboard/dashboards/project/routers/ports/views.py
deleted file mode 100644
index ea08080f..00000000
--- a/openstack_dashboard/dashboards/project/routers/ports/views.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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 logging
-
-from django.core.urlresolvers import reverse
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tabs
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.project.routers.ports.forms \
- import AddInterface
-from openstack_dashboard.dashboards.project.routers.ports.forms \
- import SetGatewayForm
-from openstack_dashboard.dashboards.project.routers.ports.tabs \
- import PortDetailTabs
-
-
-LOG = logging.getLogger(__name__)
-
-
-class AddInterfaceView(forms.ModalFormView):
- form_class = AddInterface
- template_name = 'project/routers/ports/create.html'
- success_url = 'horizon:project:routers:detail'
- failure_url = 'horizon:project:routers:detail'
-
- def get_success_url(self):
- return reverse(self.success_url,
- args=(self.kwargs['router_id'],))
-
- def get_object(self):
- if not hasattr(self, "_object"):
- try:
- router_id = self.kwargs["router_id"]
- self._object = api.neutron.router_get(self.request,
- router_id)
- except:
- redirect = reverse(self.failure_url, args=[router_id])
- msg = _("Unable to retrieve router.")
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_context_data(self, **kwargs):
- context = super(AddInterfaceView, self).get_context_data(**kwargs)
- context['router'] = self.get_object()
- return context
-
- def get_initial(self):
- router = self.get_object()
- return {"router_id": self.kwargs['router_id'],
- "router_name": router.name}
-
-
-class SetGatewayView(forms.ModalFormView):
- form_class = SetGatewayForm
- template_name = 'project/routers/ports/setgateway.html'
- success_url = 'horizon:project:routers:index'
- failure_url = 'horizon:project:routers:index'
-
- def get_success_url(self):
- return reverse(self.success_url)
-
- def get_object(self):
- if not hasattr(self, "_object"):
- try:
- router_id = self.kwargs["router_id"]
- self._object = api.neutron.router_get(self.request,
- router_id)
- except:
- redirect = reverse(self.failure_url)
- msg = _("Unable to set gateway.")
- exceptions.handle(self.request, msg, redirect=redirect)
- return self._object
-
- def get_context_data(self, **kwargs):
- context = super(SetGatewayView, self).get_context_data(**kwargs)
- context['router'] = self.get_object()
- return context
-
- def get_initial(self):
- router = self.get_object()
- return {"router_id": self.kwargs['router_id'],
- "router_name": router.name}
-
-
-class DetailView(tabs.TabView):
- tab_group_class = PortDetailTabs
- template_name = 'project/networks/ports/detail.html'
diff --git a/openstack_dashboard/dashboards/project/routers/tables.py b/openstack_dashboard/dashboards/project/routers/tables.py
deleted file mode 100644
index c86680e0..00000000
--- a/openstack_dashboard/dashboards/project/routers/tables.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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 logging
-
-from django.core.urlresolvers import reverse
-from django.template.defaultfilters import title
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import messages
-from horizon import tables
-from neutronclient.common import exceptions as q_ext
-from openstack_dashboard import api
-
-LOG = logging.getLogger(__name__)
-
-
-class DeleteRouter(tables.DeleteAction):
- data_type_singular = _("Router")
- data_type_plural = _("Routers")
- redirect_url = "horizon:project:routers:index"
-
- def delete(self, request, obj_id):
- obj = self.table.get_object_by_id(obj_id)
- name = self.table.get_object_display(obj)
- try:
- api.neutron.router_delete(request, obj_id)
- except q_ext.NeutronClientException as e:
- msg = _('Unable to delete router "%s"') % e.message
- LOG.info(msg)
- messages.error(request, msg)
- redirect = reverse(self.redirect_url)
- raise exceptions.Http302(redirect, message=msg)
- except Exception as e:
- msg = _('Unable to delete router "%s"') % name
- LOG.info(msg)
- exceptions.handle(request, msg)
-
- def allowed(self, request, router=None):
- return True
-
-
-class CreateRouter(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Router")
- url = "horizon:project:routers:create"
- classes = ("ajax-modal", "btn-create")
-
-
-class SetGateway(tables.LinkAction):
- name = "setgateway"
- verbose_name = _("Set Gateway")
- url = "horizon:project:routers:setgateway"
- classes = ("ajax-modal", "btn-camera")
-
- def allowed(self, request, datum=None):
- if datum.external_gateway_info:
- return False
- return True
-
-
-class ClearGateway(tables.BatchAction):
- name = "cleargateway"
- action_present = _("Clear")
- action_past = _("Cleared")
- data_type_singular = _("Gateway")
- data_type_plural = _("Gateways")
- classes = ('btn-danger', 'btn-cleargateway')
- redirect_url = "horizon:project:routers:index"
-
- def action(self, request, obj_id):
- obj = self.table.get_object_by_id(obj_id)
- name = self.table.get_object_display(obj)
- try:
- api.neutron.router_remove_gateway(request, obj_id)
- except Exception as e:
- msg = (_('Unable to clear gateway for router '
- '"%(name)s": "%(msg)s"')
- % {"name": name, "msg": e.message})
- LOG.info(msg)
- redirect = reverse(self.redirect_url)
- exceptions.handle(request, msg, redirect=redirect)
-
- def get_success_url(self, request):
- return reverse(self.redirect_url)
-
- def allowed(self, request, datum=None):
- if datum.external_gateway_info:
- return True
- return False
-
-
-class UpdateRow(tables.Row):
- ajax = True
-
- def get_data(self, request, router_id):
- router = api.neutron.router_get(request, router_id)
- return router
-
-
-def get_external_network(router):
- if router.external_gateway_info:
- return router.external_gateway_info['network']
- else:
- return "-"
-
-
-class RoutersTable(tables.DataTable):
- name = tables.Column("name",
- verbose_name=_("Name"),
- link="horizon:project:routers:detail")
- status = tables.Column("status",
- filters=(title,),
- verbose_name=_("Status"),
- status=True)
- ext_net = tables.Column(get_external_network,
- verbose_name=_("External Network"))
-
- def get_object_display(self, obj):
- return obj.name
-
- class Meta:
- name = "Routers"
- verbose_name = _("Routers")
- status_columns = ["status"]
- row_class = UpdateRow
- table_actions = (CreateRouter, DeleteRouter)
- row_actions = (SetGateway, ClearGateway, DeleteRouter)
diff --git a/openstack_dashboard/dashboards/project/routers/tabs.py b/openstack_dashboard/dashboards/project/routers/tabs.py
deleted file mode 100644
index dceb5a26..00000000
--- a/openstack_dashboard/dashboards/project/routers/tabs.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-from openstack_dashboard import api
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "overview"
- template_name = ("project/routers/_detail_overview.html")
- redirect_url = 'horizon:project:routers:index'
-
- def get_context_data(self, request):
- router_id = self.tab_group.kwargs['router_id']
- try:
- router = api.neutron.router_get(request, router_id)
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve router details.'),
- redirect=reverse(self.redirect_url))
- return {'router': router}
-
-
-class RouterDetailTabs(tabs.TabGroup):
- slug = "router_details"
- tabs = (OverviewTab,)
diff --git a/openstack_dashboard/dashboards/project/routers/templates/routers/_create.html b/openstack_dashboard/dashboards/project/routers/templates/routers/_create.html
deleted file mode 100644
index 38d03617..00000000
--- a/openstack_dashboard/dashboards/project/routers/templates/routers/_create.html
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n horizon humanize %}
-{% load url from future %}
-
-{% block form_id %}{% endblock %}
-{% block form_action %}{% url 'horizon:project:routers:create' %}?{{ request.GET.urlencode }}{% endblock %}
-
-{% block modal_id %}create_router_modal{% endblock %}
-{% block modal-header %}{% trans "Create router" %}{% endblock %}
-
-{% block modal-body %}
- <div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
- </div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create router" %}" />
- <a href="{% url 'horizon:project:routers:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/routers/templates/routers/_detail_overview.html b/openstack_dashboard/dashboards/project/routers/templates/routers/_detail_overview.html
deleted file mode 100644
index 226939f6..00000000
--- a/openstack_dashboard/dashboards/project/routers/templates/routers/_detail_overview.html
+++ /dev/null
@@ -1,20 +0,0 @@
-{% load i18n sizeformat parse_date %}
-
-<h3>{% trans "Router Overview" %}: {{router.name|default:_("None") }}</h3>
-
-<div class="info detail">
- <dl>
- <dt>{% trans "Name" %}</dt>
- <dd>{{ router.name|default:_("None") }}</dd>
- <dt>{% trans "ID" %}</dt>
- <dd>{{ router.id|default:_("None") }}</dd>
- <dt>{% trans "Status" %}</dt>
- <dd>{{ router.status|default:_("Unknown") }}</dd>
- {% if router.external_gateway_info %}
- <dt>{% trans "External Gateway Information" %}</dt>
- <dd>{% trans "Connected External Network" %}:
- {{ router.external_gateway_info.network }}</dd>
- {% endif %}
- </dl>
-</div>
-
diff --git a/openstack_dashboard/dashboards/project/routers/templates/routers/create.html b/openstack_dashboard/dashboards/project/routers/templates/routers/create.html
deleted file mode 100644
index 54a7b44a..00000000
--- a/openstack_dashboard/dashboards/project/routers/templates/routers/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Router" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create Router") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/routers/_create.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/routers/templates/routers/detail.html b/openstack_dashboard/dashboards/project/routers/templates/routers/detail.html
deleted file mode 100644
index 8cb5a883..00000000
--- a/openstack_dashboard/dashboards/project/routers/templates/routers/detail.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Router Details" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Router Details") %}
-{% endblock page_header %}
-
-{% block main %}
-{% include "project/routers/_detail_overview.html" %}
-<hr>
-<div id="interfaces">
- {{ interfaces_table.render }}
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/routers/templates/routers/index.html b/openstack_dashboard/dashboards/project/routers/templates/routers/index.html
deleted file mode 100644
index 8389f15a..00000000
--- a/openstack_dashboard/dashboards/project/routers/templates/routers/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Routers" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Routers") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/routers/templates/routers/ports/_create.html b/openstack_dashboard/dashboards/project/routers/templates/routers/ports/_create.html
deleted file mode 100644
index 426569d2..00000000
--- a/openstack_dashboard/dashboards/project/routers/templates/routers/ports/_create.html
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}add_interface_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:routers:addinterface' router.id %}
-{% endblock %}
-
-{% block modal-header %}{% trans "Add Interface" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>
- {% trans "You can connect a specified subnet to the router." %}
- </p>
- <p>
- {% trans "The default IP address of the interface created is a gateway of the selected subnet. You can specify another IP address of the interface here. You must select a subnet to which the specified IP address belongs to from the above list." %}
- </p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Add interface" %}" />
- <a href="{% url 'horizon:project:routers:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/routers/templates/routers/ports/_setgateway.html b/openstack_dashboard/dashboards/project/routers/templates/routers/ports/_setgateway.html
deleted file mode 100644
index 17279283..00000000
--- a/openstack_dashboard/dashboards/project/routers/templates/routers/ports/_setgateway.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}setgateway_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:routers:setgateway' router.id %}
-{% endblock %}
-
-{% block modal-header %}{% trans "Set Gateway" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "You can connect a specified external network to the router. The external network is regarded as a default route of the router and the router acts as a gateway for external connectivity." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Set Gateway" %}" />
- <a href="{% url 'horizon:project:routers:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/routers/templates/routers/ports/create.html b/openstack_dashboard/dashboards/project/routers/templates/routers/ports/create.html
deleted file mode 100644
index 300b8d15..00000000
--- a/openstack_dashboard/dashboards/project/routers/templates/routers/ports/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Add Interface" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Add Interface") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "project/routers/ports/_create.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/routers/templates/routers/ports/setgateway.html b/openstack_dashboard/dashboards/project/routers/templates/routers/ports/setgateway.html
deleted file mode 100644
index 5c966b88..00000000
--- a/openstack_dashboard/dashboards/project/routers/templates/routers/ports/setgateway.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Set Gateway" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Set Gateway") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "project/routers/ports/_setgateway.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/routers/tests.py b/openstack_dashboard/dashboards/project/routers/tests.py
deleted file mode 100644
index 9509d8b0..00000000
--- a/openstack_dashboard/dashboards/project/routers/tests.py
+++ /dev/null
@@ -1,317 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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.core.urlresolvers import reverse
-from django import http
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class RouterTests(test.TestCase):
- DASHBOARD = 'project'
- INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD)
- DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD
-
- def _mock_external_network_list(self):
- search_opts = {'router:external': True}
- ext_nets = [n for n in self.networks.list() if n['router:external']]
- api.neutron.network_list(
- IsA(http.HttpRequest),
- **search_opts).AndReturn(ext_nets)
-
- def _mock_external_network_get(self, router):
- ext_net_id = router.external_gateway_info['network_id']
- ext_net = self.networks.list()[2]
- api.neutron.network_get(IsA(http.HttpRequest), ext_net_id,
- expand_subnet=False).AndReturn(ext_net)
-
- @test.create_stubs({api.neutron: ('router_list', 'network_list')})
- def test_index(self):
- api.neutron.router_list(
- IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- search_opts=None).AndReturn(self.routers.list())
- self._mock_external_network_list()
- self.mox.ReplayAll()
-
- res = self.client.get(self.INDEX_URL)
-
- self.assertTemplateUsed(res, '%s/routers/index.html' % self.DASHBOARD)
- routers = res.context['table'].data
- self.assertItemsEqual(routers, self.routers.list())
-
- @test.create_stubs({api.neutron: ('router_list', 'network_list')})
- def test_index_router_list_exception(self):
- api.neutron.router_list(
- IsA(http.HttpRequest),
- tenant_id=self.tenant.id,
- search_opts=None).AndRaise(self.exceptions.neutron)
- self._mock_external_network_list()
- self.mox.ReplayAll()
-
- res = self.client.get(self.INDEX_URL)
-
- self.assertTemplateUsed(res, '%s/routers/index.html' % self.DASHBOARD)
- self.assertEqual(len(res.context['table'].data), 0)
- self.assertMessageCount(res, error=1)
-
- @test.create_stubs({api.neutron: ('router_get', 'port_list',
- 'network_get')})
- def test_router_detail(self):
- router = self.routers.first()
- api.neutron.router_get(IsA(http.HttpRequest), router.id)\
- .AndReturn(self.routers.first())
- api.neutron.port_list(IsA(http.HttpRequest),
- device_id=router.id)\
- .AndReturn([self.ports.first()])
- self._mock_external_network_get(router)
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:%s'
- ':routers:detail' % self.DASHBOARD,
- args=[router.id]))
-
- self.assertTemplateUsed(res, '%s/routers/detail.html' % self.DASHBOARD)
- ports = res.context['interfaces_table'].data
- self.assertItemsEqual(ports, [self.ports.first()])
-
- @test.create_stubs({api.neutron: ('router_get', 'port_list')})
- def test_router_detail_exception(self):
- router = self.routers.first()
- api.neutron.router_get(IsA(http.HttpRequest), router.id)\
- .AndRaise(self.exceptions.neutron)
- api.neutron.port_list(IsA(http.HttpRequest),
- device_id=router.id)\
- .AndReturn([self.ports.first()])
- self.mox.ReplayAll()
-
- res = self.client.get(reverse('horizon:%s'
- ':routers:detail' % self.DASHBOARD,
- args=[router.id]))
- self.assertRedirectsNoFollow(res, self.INDEX_URL)
-
-
-class RouterActionTests(test.TestCase):
- DASHBOARD = 'project'
- INDEX_URL = reverse('horizon:%s:routers:index' % DASHBOARD)
- DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD
-
- @test.create_stubs({api.neutron: ('router_create',)})
- def test_router_create_post(self):
- router = self.routers.first()
- api.neutron.router_create(IsA(http.HttpRequest), name=router.name)\
- .AndReturn(router)
- self.mox.ReplayAll()
-
- form_data = {'name': router.name}
- url = reverse('horizon:%s:routers:create' % self.DASHBOARD)
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, self.INDEX_URL)
-
- @test.create_stubs({api.neutron: ('router_create',)})
- def test_router_create_post_exception(self):
- router = self.routers.first()
- api.neutron.router_create(IsA(http.HttpRequest), name=router.name)\
- .AndRaise(self.exceptions.neutron)
- self.mox.ReplayAll()
-
- form_data = {'name': router.name}
- url = reverse('horizon:%s:routers:create' % self.DASHBOARD)
- res = self.client.post(url, form_data)
-
- self.assertNoFormErrors(res)
- self.assertRedirectsNoFollow(res, self.INDEX_URL)
-
- def _mock_network_list(self, tenant_id):
- api.neutron.network_list(
- IsA(http.HttpRequest),
- shared=False,
- tenant_id=tenant_id).AndReturn(self.networks.list())
- api.neutron.network_list(
- IsA(http.HttpRequest),
- shared=True).AndReturn([])
-
- def _test_router_addinterface(self, raise_error=False):
- router = self.routers.first()
- subnet = self.subnets.first()
- port = self.ports.first()
-
- add_interface = api.neutron.router_add_interface(
- IsA(http.HttpRequest), router.id, subnet_id=subnet.id)
- if raise_error:
- add_interface.AndRaise(self.exceptions.neutron)
- else:
- add_interface.AndReturn({'subnet_id': subnet.id,
- 'port_id': port.id})
- api.neutron.port_get(IsA(http.HttpRequest), port.id)\
- .AndReturn(port)
- self._check_router_addinterface(router, subnet)
-
- def _check_router_addinterface(self, router, subnet, ip_address=''):
- # mock APIs used to show router detail
- api.neutron.router_get(IsA(http.HttpRequest), router.id)\
- .AndReturn(router)
- self._mock_network_list(router['tenant_id'])
- self.mox.ReplayAll()
-
- form_data = {'router_id': router.id,
- 'router_name': router.name,
- 'subnet_id': subnet.id,
- 'ip_address': ip_address}
-
- url = reverse('horizon:%s:routers:addinterface' % self.DASHBOARD,
- args=[router.id])
- res = self.client.post(url, form_data)
- self.assertNoFormErrors(res)
- detail_url = reverse(self.DETAIL_PATH, args=[router.id])
- self.assertRedirectsNoFollow(res, detail_url)
-
- @test.create_stubs({api.neutron: ('router_get',
- 'router_add_interface',
- 'port_get',
- 'network_list')})
- def test_router_addinterface(self):
- self._test_router_addinterface()
-
- @test.create_stubs({api.neutron: ('router_get',
- 'router_add_interface',
- 'network_list')})
- def test_router_addinterface_exception(self):
- self._test_router_addinterface(raise_error=True)
-
- def _test_router_addinterface_ip_addr(self, errors=[]):
- router = self.routers.first()
- subnet = self.subnets.first()
- port = self.ports.first()
- ip_addr = port['fixed_ips'][0]['ip_address']
- self._setup_mock_addinterface_ip_addr(router, subnet, port,
- ip_addr, errors)
- self._check_router_addinterface(router, subnet, ip_addr)
-
- def _setup_mock_addinterface_ip_addr(self, router, subnet, port,
- ip_addr, errors=[]):
- subnet_get = api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)
- if 'subnet_get' in errors:
- subnet_get.AndRaise(self.exceptions.neutron)
- return
- subnet_get.AndReturn(subnet)
-
- params = {'network_id': subnet.network_id,
- 'fixed_ips': [{'subnet_id': subnet.id,
- 'ip_address': ip_addr}]}
- port_create = api.neutron.port_create(IsA(http.HttpRequest), **params)
- if 'port_create' in errors:
- port_create.AndRaise(self.exceptions.neutron)
- return
- port_create.AndReturn(port)
-
- add_inf = api.neutron.router_add_interface(
- IsA(http.HttpRequest), router.id, port_id=port.id)
- if 'add_interface' not in errors:
- return
-
- add_inf.AndRaise(self.exceptions.neutron)
- port_delete = api.neutron.port_delete(IsA(http.HttpRequest), port.id)
- if 'port_delete' in errors:
- port_delete.AndRaise(self.exceptions.neutron)
-
- @test.create_stubs({api.neutron: ('router_add_interface', 'subnet_get',
- 'port_create',
- 'router_get', 'network_list')})
- def test_router_addinterface_ip_addr(self):
- self._test_router_addinterface_ip_addr()
-
- @test.create_stubs({api.neutron: ('subnet_get',
- 'router_get', 'network_list')})
- def test_router_addinterface_ip_addr_exception_subnet_get(self):
- self._test_router_addinterface_ip_addr(errors=['subnet_get'])
-
- @test.create_stubs({api.neutron: ('subnet_get', 'port_create',
- 'router_get', 'network_list')})
- def test_router_addinterface_ip_addr_exception_port_create(self):
- self._test_router_addinterface_ip_addr(errors=['port_create'])
-
- @test.create_stubs({api.neutron: ('router_add_interface', 'subnet_get',
- 'port_create', 'port_delete',
- 'router_get', 'network_list')})
- def test_router_addinterface_ip_addr_exception_add_interface(self):
- self._test_router_addinterface_ip_addr(errors=['add_interface'])
-
- @test.create_stubs({api.neutron: ('router_add_interface', 'subnet_get',
- 'port_create', 'port_delete',
- 'router_get', 'network_list')})
- def test_router_addinterface_ip_addr_exception_port_delete(self):
- self._test_router_addinterface_ip_addr(errors=['add_interface',
- 'port_delete'])
-
- @test.create_stubs({api.neutron: ('router_get',
- 'router_add_gateway',
- 'network_list')})
- def test_router_add_gateway(self):
- router = self.routers.first()
- network = self.networks.first()
- api.neutron.router_add_gateway(
- IsA(http.HttpRequest),
- router.id,
- network.id).AndReturn(None)
- api.neutron.router_get(
- IsA(http.HttpRequest), router.id).AndReturn(router)
- search_opts = {'router:external': True}
- api.neutron.network_list(
- IsA(http.HttpRequest), **search_opts).AndReturn([network])
- self.mox.ReplayAll()
-
- form_data = {'router_id': router.id,
- 'router_name': router.name,
- 'network_id': network.id}
-
- url = reverse('horizon:%s:routers:setgateway' % self.DASHBOARD,
- args=[router.id])
- res = self.client.post(url, form_data)
- self.assertNoFormErrors(res)
- detail_url = self.INDEX_URL
- self.assertRedirectsNoFollow(res, detail_url)
-
- @test.create_stubs({api.neutron: ('router_get',
- 'router_add_gateway',
- 'network_list')})
- def test_router_add_gateway_exception(self):
- router = self.routers.first()
- network = self.networks.first()
- api.neutron.router_add_gateway(
- IsA(http.HttpRequest),
- router.id,
- network.id).AndRaise(self.exceptions.neutron)
- api.neutron.router_get(
- IsA(http.HttpRequest), router.id).AndReturn(router)
- search_opts = {'router:external': True}
- api.neutron.network_list(
- IsA(http.HttpRequest), **search_opts).AndReturn([network])
- self.mox.ReplayAll()
-
- form_data = {'router_id': router.id,
- 'router_name': router.name,
- 'network_id': network.id}
-
- url = reverse('horizon:%s:routers:setgateway' % self.DASHBOARD,
- args=[router.id])
- res = self.client.post(url, form_data)
- self.assertNoFormErrors(res)
- detail_url = self.INDEX_URL
- self.assertRedirectsNoFollow(res, detail_url)
diff --git a/openstack_dashboard/dashboards/project/routers/urls.py b/openstack_dashboard/dashboards/project/routers/urls.py
deleted file mode 100644
index f7ed2f2f..00000000
--- a/openstack_dashboard/dashboards/project/routers/urls.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.routers.ports.views \
- import AddInterfaceView
-from openstack_dashboard.dashboards.project.routers.ports.views \
- import SetGatewayView
-from openstack_dashboard.dashboards.project.routers.views import CreateView
-from openstack_dashboard.dashboards.project.routers.views import DetailView
-from openstack_dashboard.dashboards.project.routers.views import IndexView
-
-
-urlpatterns = patterns('horizon.dashboards.project.routers.views',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^create/$', CreateView.as_view(), name='create'),
- url(r'^(?P<router_id>[^/]+)/$',
- DetailView.as_view(),
- name='detail'),
- url(r'^(?P<router_id>[^/]+)/addinterface', AddInterfaceView.as_view(),
- name='addinterface'),
- url(r'^(?P<router_id>[^/]+)/setgateway',
- SetGatewayView.as_view(),
- name='setgateway'),
-)
diff --git a/openstack_dashboard/dashboards/project/routers/views.py b/openstack_dashboard/dashboards/project/routers/views.py
deleted file mode 100644
index a4c06f95..00000000
--- a/openstack_dashboard/dashboards/project/routers/views.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012, Nachi Ueno, NTT MCL, 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.
-
-"""
-Views for managing Neutron Routers.
-"""
-
-import logging
-
-from django.core.urlresolvers import reverse_lazy
-from django.utils.datastructures import SortedDict
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.project.routers.forms import CreateForm
-from openstack_dashboard.dashboards.project.routers.ports.tables \
- import PortsTable
-from openstack_dashboard.dashboards.project.routers.tables import RoutersTable
-
-
-LOG = logging.getLogger(__name__)
-
-
-class IndexView(tables.DataTableView):
- table_class = RoutersTable
- template_name = 'project/routers/index.html'
-
- def _get_routers(self, search_opts=None):
- try:
- tenant_id = self.request.user.tenant_id
- routers = api.neutron.router_list(self.request,
- tenant_id=tenant_id,
- search_opts=search_opts)
- except:
- routers = []
- exceptions.handle(self.request,
- _('Unable to retrieve router list.'))
-
- ext_net_dict = self._list_external_networks()
-
- for r in routers:
- r.set_id_as_name_if_empty()
- self._set_external_network(r, ext_net_dict)
- return routers
-
- def get_data(self):
- routers = self._get_routers()
- return routers
-
- def _list_external_networks(self):
- try:
- search_opts = {'router:external': True}
- ext_nets = api.neutron.network_list(self.request,
- **search_opts)
- for ext_net in ext_nets:
- ext_net.set_id_as_name_if_empty()
- ext_net_dict = SortedDict((n['id'], n.name) for n in ext_nets)
- except Exception as e:
- msg = _('Unable to retrieve a list of external networks "%s".') % e
- exceptions.handle(self.request, msg)
- ext_net_dict = {}
- return ext_net_dict
-
- def _set_external_network(self, router, ext_net_dict):
- gateway_info = router.external_gateway_info
- if gateway_info:
- ext_net_id = gateway_info['network_id']
- if ext_net_id in ext_net_dict:
- gateway_info['network'] = ext_net_dict[ext_net_id]
- else:
- msg = _('External network "%s" not found.') % (ext_net_id)
- exceptions.handle(self.request, msg)
-
-
-class DetailView(tables.MultiTableView):
- table_classes = (PortsTable, )
- template_name = 'project/routers/detail.html'
- failure_url = reverse_lazy('horizon:project:routers:index')
-
- def _get_data(self):
- if not hasattr(self, "_router"):
- try:
- router_id = self.kwargs['router_id']
- router = api.neutron.router_get(self.request, router_id)
- router.set_id_as_name_if_empty(length=0)
- except:
- msg = _('Unable to retrieve details for router "%s".') \
- % (router_id)
- exceptions.handle(self.request, msg, redirect=self.failure_url)
-
- if router.external_gateway_info:
- ext_net_id = router.external_gateway_info['network_id']
- try:
- ext_net = api.neutron.network_get(self.request, ext_net_id,
- expand_subnet=False)
- ext_net.set_id_as_name_if_empty(length=0)
- router.external_gateway_info['network'] = ext_net.name
- except Exception:
- msg = _('Unable to retrieve an external network "%s".') \
- % (ext_net_id)
- exceptions.handle(self.request, msg)
- router.external_gateway_info['network'] = ext_net_id
-
- self._router = router
- return self._router
-
- def get_context_data(self, **kwargs):
- context = super(DetailView, self).get_context_data(**kwargs)
- context["router"] = self._get_data()
- return context
-
- def get_interfaces_data(self):
- try:
- device_id = self.kwargs['router_id']
- ports = api.neutron.port_list(self.request,
- device_id=device_id)
- except:
- ports = []
- msg = _('Port list can not be retrieved.')
- exceptions.handle(self.request, msg)
- for p in ports:
- p.set_id_as_name_if_empty()
- return ports
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateForm
- template_name = 'project/routers/create.html'
- success_url = reverse_lazy("horizon:project:routers:index")
diff --git a/openstack_dashboard/dashboards/project/stacks/__init__.py b/openstack_dashboard/dashboards/project/stacks/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/stacks/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/stacks/api.py b/openstack_dashboard/dashboards/project/stacks/api.py
deleted file mode 100644
index 319bfe23..00000000
--- a/openstack_dashboard/dashboards/project/stacks/api.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import json
-import logging
-
-from openstack_dashboard.api.heat import resources_list
-from openstack_dashboard.api.heat import stack_get
-
-from openstack_dashboard.dashboards.project.stacks.mappings \
- import get_resource_image
-from openstack_dashboard.dashboards.project.stacks.mappings \
- import get_resource_status
-from openstack_dashboard.dashboards.project.stacks.sro import resource_info
-from openstack_dashboard.dashboards.project.stacks.sro import stack_info
-
-
-LOG = logging.getLogger(__name__)
-
-
-class Stack(object):
- pass
-
-
-def d3_data(request, stack_id=''):
- try:
- stack = stack_get(request, stack_id)
- except:
- stack = Stack()
- stack.id = stack_id
- stack.stack_name = request.session.get('stack_name', '')
- stack.stack_status = 'DELETE_COMPLETE'
- stack.stack_status_reason = 'DELETE_COMPLETE'
-
- try:
- resources = resources_list(request, stack.stack_name)
- except:
- resources = []
-
- d3_data = {"nodes": [], "stack": {}}
- if stack:
- stack_image = get_resource_image(stack.stack_status, 'stack')
- stack_node = {
- 'stack_id': stack.id,
- 'name': stack.stack_name,
- 'status': stack.stack_status,
- 'image': stack_image,
- 'image_size': 60,
- 'image_x': -30,
- 'image_y': -30,
- 'text_x': 40,
- 'text_y': ".35em",
- 'in_progress': True if (get_resource_status(stack.stack_status) ==
- 'IN_PROGRESS') else False,
- 'info_box': stack_info(stack, stack_image)
- }
- d3_data['stack'] = stack_node
-
- if resources:
- for resource in resources:
- resource_image = get_resource_image(resource.resource_status,
- resource.resource_type)
- in_progress = True if (
- get_resource_status(resource.resource_status)
- == 'IN_PROGRESS') else False
- resource_node = {
- 'name': resource.logical_resource_id,
- 'status': resource.resource_status,
- 'image': resource_image,
- 'required_by': resource.required_by,
- 'image_size': 50,
- 'image_x': -25,
- 'image_y': -25,
- 'text_x': 35,
- 'text_y': ".35em",
- 'in_progress': in_progress,
- 'info_box': resource_info(resource)
- }
- d3_data['nodes'].append(resource_node)
- return json.dumps(d3_data)
diff --git a/openstack_dashboard/dashboards/project/stacks/forms.py b/openstack_dashboard/dashboards/project/stacks/forms.py
deleted file mode 100644
index d7b09355..00000000
--- a/openstack_dashboard/dashboards/project/stacks/forms.py
+++ /dev/null
@@ -1,260 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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 json
-import logging
-import re
-
-from django.utils.translation import ugettext_lazy as _
-from django.views.decorators.debug import sensitive_variables
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-
-LOG = logging.getLogger(__name__)
-
-
-def exception_to_validation_msg(e):
- '''
- Extracts a validation message to display to the user.
- This needs to be a pattern matching approach until the Heat
- API returns exception data in a parsable format.
- '''
- validation_patterns = [
- "Remote error: \w* {'Error': '(.*?)'}",
- 'Remote error: \w* (.*?) \[',
- '400 Bad Request\n\nThe server could not comply with the request '
- 'since it is either malformed or otherwise incorrect.\n\n (.*)',
- '(ParserError: .*)'
- ]
-
- for pattern in validation_patterns:
- match = re.search(pattern, str(e))
- if match:
- return match.group(1)
-
-
-class TemplateForm(forms.SelfHandlingForm):
-
- class Meta:
- name = _('Select Template')
- help_text = _('From here you can select a template to launch '
- 'a stack.')
-
- template_source = forms.ChoiceField(label=_('Template Source'),
- choices=[('url', _('URL')),
- ('file', _('File')),
- ('raw', _('Direct Input'))],
- widget=forms.Select(attrs={
- 'class': 'switchable',
- 'data-slug': 'source'}))
- template_upload = forms.FileField(
- label=_('Template File'),
- help_text=_('A local template to upload.'),
- widget=forms.FileInput(attrs={'class': 'switched',
- 'data-switch-on': 'source',
- 'data-source-file': _('Template File')}),
- required=False)
- template_url = forms.URLField(
- label=_('Template URL'),
- help_text=_('An external (HTTP) URL to load the template from.'),
- widget=forms.TextInput(attrs={'class': 'switched',
- 'data-switch-on': 'source',
- 'data-source-url': _('Template URL')}),
- required=False)
- template_data = forms.CharField(
- label=_('Template Data'),
- help_text=_('The raw contents of the template.'),
- widget=forms.widgets.Textarea(attrs={
- 'class': 'switched',
- 'data-switch-on': 'source',
- 'data-source-raw': _('Template Data')}),
- required=False)
-
- def __init__(self, *args, **kwargs):
- self.next_view = kwargs.pop('next_view')
- super(TemplateForm, self).__init__(*args, **kwargs)
-
- def clean(self):
- cleaned = super(TemplateForm, self).clean()
- template_url = cleaned.get('template_url')
- template_data = cleaned.get('template_data')
- files = self.request.FILES
- has_upload = 'template_upload' in files
-
- # Uploaded file handler
- if has_upload and not template_url:
- log_template_name = self.request.FILES['template_upload'].name
- LOG.info('got upload %s' % log_template_name)
-
- tpl = self.request.FILES['template_upload'].read()
- if tpl.startswith('{'):
- try:
- json.loads(tpl)
- except Exception as e:
- msg = _('There was a problem parsing the template: %s') % e
- raise forms.ValidationError(msg)
- cleaned['template_data'] = tpl
-
- # URL handler
- elif template_url and (has_upload or template_data):
- msg = _('Please specify a template using only one source method.')
- raise forms.ValidationError(msg)
-
- # Check for raw template input
- elif not template_url and not template_data:
- msg = _('You must specify a template via one of the '
- 'available sources.')
- raise forms.ValidationError(msg)
-
- # Validate the template and get back the params.
- kwargs = {}
- if cleaned['template_data']:
- kwargs['template'] = cleaned['template_data']
- else:
- kwargs['template_url'] = cleaned['template_url']
-
- try:
- validated = api.heat.template_validate(self.request, **kwargs)
- cleaned['template_validate'] = validated
- except Exception as e:
- msg = exception_to_validation_msg(e)
- if not msg:
- msg = _('An unknown problem occurred validating the template.')
- LOG.exception(msg)
- raise forms.ValidationError(msg)
-
- return cleaned
-
- def handle(self, request, data):
- kwargs = {'parameters': data['template_validate'],
- 'template_data': data['template_data'],
- 'template_url': data['template_url']}
- # NOTE (gabriel): This is a bit of a hack, essentially rewriting this
- # request so that we can chain it as an input to the next view...
- # but hey, it totally works.
- request.method = 'GET'
- return self.next_view.as_view()(request, **kwargs)
-
-
-class StackCreateForm(forms.SelfHandlingForm):
-
- param_prefix = '__param_'
-
- class Meta:
- name = _('Create Stack')
-
- template_data = forms.CharField(
- widget=forms.widgets.HiddenInput,
- required=False)
- template_url = forms.CharField(
- widget=forms.widgets.HiddenInput,
- required=False)
- parameters = forms.CharField(
- widget=forms.widgets.HiddenInput,
- required=True)
- stack_name = forms.CharField(
- max_length='255',
- label=_('Stack Name'),
- help_text=_('Name of the stack to create.'),
- required=True)
- timeout_mins = forms.IntegerField(
- initial=60,
- label=_('Creation Timeout (minutes)'),
- help_text=_('Stack creation timeout in minutes.'),
- required=True)
- enable_rollback = forms.BooleanField(
- label=_('Rollback On Failure'),
- help_text=_('Enable rollback on create/update failure.'),
- required=False)
-
- def __init__(self, *args, **kwargs):
- parameters = kwargs.pop('parameters')
- super(StackCreateForm, self).__init__(*args, **kwargs)
- self._build_parameter_fields(parameters)
-
- def _build_parameter_fields(self, template_validate):
-
- self.fields['password'] = forms.CharField(
- label=_('Password for user "%s"') % self.request.user.username,
- help_text=_('This is required for operations to be performed '
- 'throughout the lifecycle of the stack'),
- required=True,
- widget=forms.PasswordInput())
-
- self.help_text = template_validate['Description']
-
- params = template_validate.get('Parameters', {})
-
- for param_key, param in params.items():
- field_key = self.param_prefix + param_key
- field_args = {
- 'initial': param.get('Default', None),
- 'label': param_key,
- 'help_text': param.get('Description', ''),
- 'required': param.get('Default', None) is None
- }
-
- param_type = param.get('Type', None)
-
- if 'AllowedValues' in param:
- choices = map(lambda x: (x, x), param['AllowedValues'])
- field_args['choices'] = choices
- field = forms.ChoiceField(**field_args)
-
- elif param_type in ('CommaDelimitedList', 'String'):
- if 'MinLength' in param:
- field_args['min_length'] = int(param['MinLength'])
- field_args['required'] = param.get('MinLength', 0) > 0
- if 'MaxLength' in param:
- field_args['max_length'] = int(param['MaxLength'])
- field = forms.CharField(**field_args)
-
- elif param_type == 'Number':
- if 'MinValue' in param:
- field_args['min_value'] = int(param['MinValue'])
- if 'MaxValue' in param:
- field_args['max_value'] = int(param['MaxValue'])
- field = forms.IntegerField(**field_args)
-
- self.fields[field_key] = field
-
- @sensitive_variables('password')
- def handle(self, request, data):
- prefix_length = len(self.param_prefix)
- params_list = [(k[prefix_length:], v) for (k, v) in data.iteritems()
- if k.startswith(self.param_prefix)]
- fields = {
- 'stack_name': data.get('stack_name'),
- 'timeout_mins': data.get('timeout_mins'),
- 'disable_rollback': not(data.get('enable_rollback')),
- 'parameters': dict(params_list),
- 'password': data.get('password')
- }
-
- if data.get('template_data'):
- fields['template'] = data.get('template_data')
- else:
- fields['template_url'] = data.get('template_url')
-
- try:
- api.heat.stack_create(self.request, **fields)
- messages.success(request, _("Stack creation started."))
- return True
- except Exception as e:
- msg = exception_to_validation_msg(e)
- exceptions.handle(request, msg or _('Stack creation failed.'))
diff --git a/openstack_dashboard/dashboards/project/stacks/mappings.py b/openstack_dashboard/dashboards/project/stacks/mappings.py
deleted file mode 100644
index ac6d526a..00000000
--- a/openstack_dashboard/dashboards/project/stacks/mappings.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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 json
-import logging
-import re
-import urlparse
-
-from django.core.urlresolvers import reverse
-from django.template.defaultfilters import register
-
-from openstack_dashboard.api.swift import FOLDER_DELIMITER
-
-LOG = logging.getLogger(__name__)
-
-
-resource_urls = {
- "AWS::EC2::Instance": {
- 'link': 'horizon:project:instances:detail'},
- "AWS::EC2::NetworkInterface": {
- 'link': 'horizon:project:networks:ports:detail'},
- "AWS::EC2::RouteTable": {
- 'link': 'horizon:project:routers:detail'},
- "AWS::EC2::Subnet": {
- 'link': 'horizon:project:networks:subnets:detail'},
- "AWS::EC2::Volume": {
- 'link': 'horizon:project:volumes:detail'},
- "AWS::EC2::VPC": {
- 'link': 'horizon:project:networks:detail'},
- "AWS::S3::Bucket": {
- 'link': 'horizon:project:containers:index'},
- "OS::Quantum::Net": {
- 'link': 'horizon:project:networks:detail'},
- "OS::Quantum::Port": {
- 'link': 'horizon:project:networks:ports:detail'},
- "OS::Quantum::Router": {
- 'link': 'horizon:project:routers:detail'},
- "OS::Quantum::Subnet": {
- 'link': 'horizon:project:networks:subnets:detail'},
- "OS::Swift::Container": {
- 'link': 'horizon:project:containers:index',
- 'format_pattern': '%s' + FOLDER_DELIMITER},
-}
-
-
-def resource_to_url(resource):
- if not resource or not resource.physical_resource_id:
- return None
-
- mapping = resource_urls.get(resource.resource_type, {})
- try:
- if 'link' not in mapping:
- return None
- format_pattern = mapping.get('format_pattern') or '%s'
- rid = format_pattern % resource.physical_resource_id
- url = reverse(mapping['link'], args=(rid,))
- except Exception as e:
- LOG.exception(e)
- return None
- return url
-
-
-@register.filter
-def stack_output(output):
- if not output:
- return u''
- if isinstance(output, dict) or isinstance(output, list):
- return u'<pre>%s</pre>' % json.dumps(output, indent=2)
- if isinstance(output, basestring):
- parts = urlparse.urlsplit(output)
- if parts.netloc and parts.scheme in ('http', 'https'):
- return u'<a href="%s" target="_blank">%s</a>' % (output, output)
- return unicode(output)
-
-
-resource_images = {
- 'LB_FAILED': '/static/dashboard/img/lb-red.svg',
- 'LB_DELETE': '/static/dashboard/img/lb-red.svg',
- 'LB_IN_PROGRESS': '/static/dashboard/img/lb-gray.gif',
- 'LB_COMPLETE': '/static/dashboard/img/lb-green.svg',
- 'DB_FAILED': '/static/dashboard/img/db-red.svg',
- 'DB_DELETE': '/static/dashboard/img/db-red.svg',
- 'DB_IN_PROGRESS': '/static/dashboard/img/db-gray.gif',
- 'DB_COMPLETE': '/static/dashboard/img/db-green.svg',
- 'STACK_FAILED': '/static/dashboard/img/stack-red.svg',
- 'STACK_DELETE': '/static/dashboard/img/stack-red.svg',
- 'STACK_IN_PROGRESS': '/static/dashboard/img/stack-gray.gif',
- 'STACK_COMPLETE': '/static/dashboard/img/stack-green.svg',
- 'SERVER_FAILED': '/static/dashboard/img/server-red.svg',
- 'SERVER_DELETE': '/static/dashboard/img/server-red.svg',
- 'SERVER_IN_PROGRESS': '/static/dashboard/img/server-gray.gif',
- 'SERVER_COMPLETE': '/static/dashboard/img/server-green.svg',
- 'UNKNOWN_FAILED': '/static/dashboard/img/unknown-red.svg',
- 'UNKNOWN_DELETE': '/static/dashboard/img/unknown-red.svg',
- 'UNKNOWN_IN_PROGRESS': '/static/dashboard/img/unknown-gray.gif',
- 'UNKNOWN_COMPLETE': '/static/dashboard/img/unknown-green.svg',
-}
-
-
-def get_resource_type(type):
- if re.search('LoadBalancer', type):
- return 'LB'
- elif re.search('DBInstance', type):
- return 'DB'
- elif re.search('Instance', type):
- return 'SERVER'
- elif re.search('stack', type):
- return 'STACK'
- else:
- return 'UNKNOWN'
-
-
-def get_resource_status(status):
- if re.search('IN_PROGRESS', status):
- return 'IN_PROGRESS'
- elif re.search('FAILED', status):
- return 'FAILED'
- elif re.search('DELETE', status):
- return 'DELETE'
- else:
- return 'COMPLETE'
-
-
-def get_resource_image(status, type):
- '''
- Sets the image url and in_progress action sw based on status.
- '''
- resource_type = get_resource_type(type)
- resource_status = get_resource_status(status)
- resource_state = resource_type + "_" + resource_status
-
- for key in resource_images:
- if key == resource_state:
- return resource_images.get(key)
diff --git a/openstack_dashboard/dashboards/project/stacks/panel.py b/openstack_dashboard/dashboards/project/stacks/panel.py
deleted file mode 100644
index 7d976573..00000000
--- a/openstack_dashboard/dashboards/project/stacks/panel.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.dashboards.project import dashboard
-
-
-class Stacks(horizon.Panel):
- name = _("Stacks")
- slug = "stacks"
- permissions = ('openstack.services.orchestration',)
-
-dashboard.Project.register(Stacks)
diff --git a/openstack_dashboard/dashboards/project/stacks/sro.py b/openstack_dashboard/dashboards/project/stacks/sro.py
deleted file mode 100644
index f385ee55..00000000
--- a/openstack_dashboard/dashboards/project/stacks/sro.py
+++ /dev/null
@@ -1,31 +0,0 @@
-from django.template.defaultfilters import title
-from django.template.loader import render_to_string
-
-from horizon.utils.filters import replace_underscores
-
-
-def stack_info(stack, stack_image):
- stack.stack_status_desc = title(replace_underscores(stack.stack_status))
- if stack.stack_status_reason:
- stack.stack_status_reason = title(
- replace_underscores(stack.stack_status_reason)
- )
- context = {}
- context['stack'] = stack
- context['stack_image'] = stack_image
- return render_to_string('project/stacks/_stack_info.html',
- context)
-
-
-def resource_info(resource):
- resource.resource_status_desc = title(
- replace_underscores(resource.resource_status)
- )
- if resource.resource_status_reason:
- resource.resource_status_reason = title(
- replace_underscores(resource.resource_status_reason)
- )
- context = {}
- context['resource'] = resource
- return render_to_string('project/stacks/_resource_info.html',
- context)
diff --git a/openstack_dashboard/dashboards/project/stacks/tables.py b/openstack_dashboard/dashboards/project/stacks/tables.py
deleted file mode 100644
index 73c7215a..00000000
--- a/openstack_dashboard/dashboards/project/stacks/tables.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.http import Http404
-from django.template.defaultfilters import timesince
-from django.template.defaultfilters import title
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import messages
-from horizon import tables
-from horizon.utils.filters import parse_isotime
-from horizon.utils.filters import replace_underscores
-
-from heatclient import exc
-
-from openstack_dashboard import api
-from openstack_dashboard.dashboards.project.stacks import mappings
-
-LOG = logging.getLogger(__name__)
-
-
-class LaunchStack(tables.LinkAction):
- name = "launch"
- verbose_name = _("Launch Stack")
- url = "horizon:project:stacks:select_template"
- classes = ("btn-create", "ajax-modal")
-
-
-class DeleteStack(tables.BatchAction):
- name = "delete"
- action_present = _("Delete")
- action_past = _("Scheduled deletion of")
- data_type_singular = _("Stack")
- data_type_plural = _("Stacks")
- classes = ('btn-danger', 'btn-terminate')
-
- def action(self, request, stack_id):
- api.heat.stack_delete(request, stack_id)
-
-
-class StacksUpdateRow(tables.Row):
- ajax = True
-
- def get_data(self, request, stack_id):
- try:
- return api.heat.stack_get(request, stack_id)
- except exc.HTTPNotFound:
- # returning 404 to the ajax call removes the
- # row from the table on the ui
- raise Http404
- except Exception as e:
- messages.error(request, e)
-
-
-class StacksTable(tables.DataTable):
- STATUS_CHOICES = (
- ("Create Complete", True),
- ("Create Failed", False),
- )
- name = tables.Column("stack_name",
- verbose_name=_("Stack Name"),
- link="horizon:project:stacks:detail",)
- created = tables.Column("creation_time",
- verbose_name=_("Created"),
- filters=(parse_isotime, timesince))
- updated = tables.Column("updated_time",
- verbose_name=_("Updated"),
- filters=(parse_isotime, timesince))
- status = tables.Column("stack_status",
- filters=(title, replace_underscores),
- verbose_name=_("Status"),
- status=True,
- status_choices=STATUS_CHOICES)
-
- def get_object_display(self, stack):
- return stack.stack_name
-
- class Meta:
- name = "stacks"
- verbose_name = _("Stacks")
- status_columns = ["status", ]
- row_class = StacksUpdateRow
- table_actions = (LaunchStack, DeleteStack,)
- row_actions = (DeleteStack, )
-
-
-class EventsTable(tables.DataTable):
-
- logical_resource = tables.Column('logical_resource_id',
- verbose_name=_("Stack Resource"),
- link=lambda d: d.logical_resource_id,)
- physical_resource = tables.Column('physical_resource_id',
- verbose_name=_("Resource"),
- link=mappings.resource_to_url)
- timestamp = tables.Column('event_time',
- verbose_name=_("Time Since Event"),
- filters=(parse_isotime, timesince))
- status = tables.Column("resource_status",
- filters=(title, replace_underscores),
- verbose_name=_("Status"),)
-
- statusreason = tables.Column("resource_status_reason",
- verbose_name=_("Status Reason"),)
-
- class Meta:
- name = "events"
- verbose_name = _("Stack Events")
-
-
-class ResourcesUpdateRow(tables.Row):
- ajax = True
-
- def get_data(self, request, resource_name):
- try:
- stack = self.table.stack
- stack_identifier = '%s/%s' % (stack.stack_name, stack.id)
- return api.heat.resource_get(
- request, stack_identifier, resource_name)
- except exc.HTTPNotFound:
- # returning 404 to the ajax call removes the
- # row from the table on the ui
- raise Http404
- except Exception as e:
- messages.error(request, e)
-
-
-class ResourcesTable(tables.DataTable):
- STATUS_CHOICES = (
- ("Create Complete", True),
- ("Create Failed", False),
- )
-
- logical_resource = tables.Column('logical_resource_id',
- verbose_name=_("Stack Resource"),
- link=lambda d: d.logical_resource_id)
- physical_resource = tables.Column('physical_resource_id',
- verbose_name=_("Resource"),
- link=mappings.resource_to_url)
- resource_type = tables.Column("resource_type",
- verbose_name=_("Stack Resource Type"),)
- updated_time = tables.Column('updated_time',
- verbose_name=_("Date Updated"),
- filters=(parse_isotime, timesince))
- status = tables.Column("resource_status",
- filters=(title, replace_underscores),
- verbose_name=_("Status"),
- status=True,
- status_choices=STATUS_CHOICES)
-
- statusreason = tables.Column("resource_status_reason",
- verbose_name=_("Status Reason"),)
-
- def __init__(self, request, data=None,
- needs_form_wrapper=None, **kwargs):
- super(ResourcesTable, self).__init__(
- request, data, needs_form_wrapper, **kwargs)
- self.stack = kwargs['stack']
-
- def get_object_id(self, datum):
- return datum.logical_resource_id
-
- class Meta:
- name = "resources"
- verbose_name = _("Stack Resources")
- status_columns = ["status", ]
- row_class = ResourcesUpdateRow
diff --git a/openstack_dashboard/dashboards/project/stacks/tabs.py b/openstack_dashboard/dashboards/project/stacks/tabs.py
deleted file mode 100644
index 9a736bb2..00000000
--- a/openstack_dashboard/dashboards/project/stacks/tabs.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import messages
-from horizon import tabs
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.project.stacks.api import d3_data
-from openstack_dashboard.dashboards.project.stacks.tables import EventsTable
-from openstack_dashboard.dashboards.project.stacks.tables import ResourcesTable
-
-
-LOG = logging.getLogger(__name__)
-
-
-class StackTopologyTab(tabs.Tab):
- name = _("Topology")
- slug = "topology"
- template_name = "project/stacks/_detail_topology.html"
- preload = False
-
- def get_context_data(self, request):
- context = {}
- stack = self.tab_group.kwargs['stack']
- context['stack_id'] = stack.id
- context['d3_data'] = d3_data(request, stack_id=stack.id)
- return context
-
-
-class StackOverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "overview"
- template_name = "project/stacks/_detail_overview.html"
-
- def get_context_data(self, request):
- return {"stack": self.tab_group.kwargs['stack']}
-
-
-class ResourceOverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "resource_overview"
- template_name = "project/stacks/_resource_overview.html"
-
- def get_context_data(self, request):
- return {
- "resource": self.tab_group.kwargs['resource'],
- "metadata": self.tab_group.kwargs['metadata']}
-
-
-class StackEventsTab(tabs.Tab):
- name = _("Events")
- slug = "events"
- template_name = "project/stacks/_detail_events.html"
- preload = False
-
- def get_context_data(self, request):
- stack = self.tab_group.kwargs['stack']
- try:
- stack_identifier = '%s/%s' % (stack.stack_name, stack.id)
- events = api.heat.events_list(self.request, stack_identifier)
- LOG.debug('got events %s' % events)
- except:
- events = []
- messages.error(request, _(
- 'Unable to get events for stack "%s".') % stack.stack_name)
- return {"stack": stack,
- "table": EventsTable(request, data=events), }
-
-
-class StackResourcesTab(tabs.Tab):
- name = _("Resources")
- slug = "resources"
- template_name = "project/stacks/_detail_resources.html"
- preload = False
-
- def get_context_data(self, request):
- stack = self.tab_group.kwargs['stack']
- try:
- stack_identifier = '%s/%s' % (stack.stack_name, stack.id)
- resources = api.heat.resources_list(self.request, stack_identifier)
- LOG.debug('got resources %s' % resources)
- except:
- resources = []
- messages.error(request, _(
- 'Unable to get resources for stack "%s".') % stack.stack_name)
- return {"stack": stack,
- "table": ResourcesTable(
- request, data=resources, stack=stack), }
-
-
-class StackDetailTabs(tabs.TabGroup):
- slug = "stack_details"
- tabs = (StackTopologyTab, StackOverviewTab, StackResourcesTab,
- StackEventsTab)
- sticky = True
-
-
-class ResourceDetailTabs(tabs.TabGroup):
- slug = "resource_details"
- tabs = (ResourceOverviewTab,)
- sticky = True
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_create.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/_create.html
deleted file mode 100644
index ab2c049b..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_create.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}launch_stack{% endblock %}
-{% block form_action %}{% url 'horizon:project:stacks:launch' %}{% endblock %}
-
-{% block modal-header %}{% trans "Launch Stack" %}{% endblock %}
-{% block modal_id %}launch_stack_modal{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "Create a new stack with the provided values." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Launch" %}" />
- <a href="{% url 'horizon:project:stacks:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_events.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_events.html
deleted file mode 100644
index 9976f88d..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_events.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{% load i18n %}
-
-{{ table.render }}
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_overview.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_overview.html
deleted file mode 100644
index f4756e07..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_overview.html
+++ /dev/null
@@ -1,66 +0,0 @@
-{% load i18n sizeformat %}
-
-<h3>{% trans "Stack Overview" %}</h3>
-
-<div class="info row-fluid detail">
- <h4>{% trans "Info" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Name" %}</dt>
- <dd>{{ stack.stack_name }}</dd>
- <dt>{% trans "ID" %}</dt>
- <dd>{{ stack.id }}</dd>
- <dt>{% trans "Description" %}</dt>
- <dd>{{ stack.description }}</dd>
- </dl>
-</div>
-
-<div class="status row-fluid detail">
- <h4>{% trans "Status" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Created" %}</dt>
- <dd>{{ stack.creation_time|parse_isotime|timesince }}</dd>
- <dt>{% trans "Last Updated" %}</dt>
- <dd>{{ stack.updated_time|parse_isotime|timesince }}</dd>
- <dt>{% trans "Status" %}</dt>
- <dd>{{ stack.stack_status|title }}: {{ stack.stack_status_reason }}</dd>
- </dl>
-</div>
-
-<div class="outputs row-fluid detail">
- <h4>{% trans "Outputs" %}</h4>
- <hr class="header_rule">
- <dl>
- {% for output in stack.outputs %}
- <dt>{{ output.output_key }}</dt>
- <dd>{{ output.description }}</dd>
- <dd>
- {% autoescape off %}
- {{ output.output_value|stack_output }}
- {% endautoescape %}</dd>
- {% endfor %}
- </dl>
-</div>
-
-<div class="parameters row-fluid detail">
- <h4>{% trans "Stack Parameters" %}</h4>
- <hr class="header_rule">
- <dl>
- {% for key, value in stack.parameters.items %}
- <dt>{{ key }}</dt>
- <dd>{{ value }}</dd>
- {% endfor %}
- </dl>
-</div>
-
-<div class="launch row-fluid detail">
- <h4>{% trans "Launch Parameters" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Timeout" %}</dt>
- <dd>{{ stack.timeout_mins }} {% trans "Minutes" %}</dd>
- <dt>{% trans "Rollback" %}</dt>
- <dd>{% if stack.disable_rollback %}{% trans "Disabled" %}{% else %}{% trans "Enabled" %}{% endif %}</dd>
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_resources.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_resources.html
deleted file mode 100644
index 9976f88d..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_resources.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{% load i18n %}
-
-{{ table.render }}
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_topology.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_topology.html
deleted file mode 100644
index d906cead..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_detail_topology.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{% load i18n sizeformat %}
-
-<div id="resource_container">
- <div id="info_box"></div>
- <div id="stack_box"></div>
- <div id="heat_resource_topology"></div>
- <div id="stack_id" data-stack_id="{{ stack_id }}"></div>
- <div id="d3_data" data-d3_data="{{ d3_data }}"></div>
-</div> \ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_resource_info.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/_resource_info.html
deleted file mode 100644
index 05a92ec3..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_resource_info.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<h3>{{ resource.logical_resource_id }}</h3>
-
-{% if resource.resource_status == 'CREATE_FAILED' %}
-<p class="error">{{ resource.resource_status_desc }}</p>
-<p class="error">{{ resource.resource_status_reason }}</p>
-{% else %}
-<p>{{ resource.resource_status_desc }}</p>
-{% endif %}
-
-<p>{{ resource.resource_type }}</p> \ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_resource_overview.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/_resource_overview.html
deleted file mode 100644
index 952c8ae4..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_resource_overview.html
+++ /dev/null
@@ -1,42 +0,0 @@
-{% load i18n sizeformat %}
-
-<h3>{% trans "Resource Overview" %}</h3>
-
-<div class="info row-fluid detail">
- <h4>{% trans "Info" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Stack Resource ID" %}</dt>
- <dd>{{ resource.logical_resource_id }}</dd>
- </dl>
- <dl>
- <dt>{% trans "Resource ID" %}</dt>
- <dd>{{ resource.physical_resource_id }}</dd>
- </dl>
- <dl>
- <dt>{% trans "Stack Resource Type" %}</dt>
- <dd>{{ resource.resource_type }}</dd>
- </dl>
- <dl>
- <dt>{% trans "Description" %}</dt>
- <dd>{{ resource.description }}</dd>
- </dl>
-</div>
-
-<div class="status row-fluid detail">
- <h4>{% trans "Status" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Last Updated" %}</dt>
- <dd>{{ resource.updated_time|parse_isotime|timesince }}</dd>
- <dt>{% trans "Status" %}</dt>
- <dd>{{ resource.resource_status|title|replace_underscores }}: {{ resource.resource_status_reason }}</dd>
- </dl>
-</div>
-
-<div class="status row-fluid detail">
- <h4>{% trans "Resource Metadata" %}</h4>
- <hr class="header_rule">
- <pre>{{ metadata }}
- </pre>
-</div>
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_select_template.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/_select_template.html
deleted file mode 100644
index c1b6261f..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_select_template.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}select_template{% endblock %}
-{% block form_action %}{% url 'horizon:project:stacks:select_template' %}{% endblock %}
-{% block form_attrs %}enctype="multipart/form-data"{% endblock %}
-
-{% block modal-header %}{% trans "Select Template" %}{% endblock %}
-{% block modal_id %}select_template_modal{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description" %}:</h3>
- <p>{% trans "Use one of the available template source options to specify the template to be used in creating this stack." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Next" %}" />
- <a href="{% url 'horizon:project:stacks:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_stack_info.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/_stack_info.html
deleted file mode 100644
index 3b548aa5..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/_stack_info.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<img src="{{ stack_image }}" width="35px" height="35px" />
-<div id="stack_info">
- <h3>{{ stack.stack_name }}</h3>
- <p class="error">{{ stack.stack_status_desc }}</p>
-</div>
-<div class="clear"></div>
-{% if stack.stack_status == 'CREATE_FAILED' %}
- <p class="error">{{ stack.stack_status_reason }}</p>
-{% else %}
- <p>{{ stack.stack_status_desc }}</p>
-{% endif %}
-{% for output in stack.outputs %}
- {% if output.output_key == 'WebsiteURL' %}
- <a href="{{ output.output_value }}">{{ output.description }}</a>
- {% endif %}
-{% endfor %} \ No newline at end of file
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/create.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/create.html
deleted file mode 100644
index 67c8f2c6..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Launch Stack" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Launch Stack") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/stacks/_create.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/detail.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/detail.html
deleted file mode 100644
index 7502167f..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/detail.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n sizeformat %}
-{% block title %}{% trans "Stack Detail" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Stack Detail: ")|add:stack.stack_name %}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/index.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/index.html
deleted file mode 100644
index 143917ad..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Stacks" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Stacks") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
-
-
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/resource.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/resource.html
deleted file mode 100644
index a9ea3021..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/resource.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n sizeformat %}
-{% block title %}{% trans "Resource Detail" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Resource Detail: ")|add:resource.logical_resource_id %}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/stacks/templates/stacks/select_template.html b/openstack_dashboard/dashboards/project/stacks/templates/stacks/select_template.html
deleted file mode 100644
index c55848d9..00000000
--- a/openstack_dashboard/dashboards/project/stacks/templates/stacks/select_template.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Select Template" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Select Template") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/stacks/_select_template.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/stacks/tests.py b/openstack_dashboard/dashboards/project/stacks/tests.py
deleted file mode 100644
index c02c7814..00000000
--- a/openstack_dashboard/dashboards/project/stacks/tests.py
+++ /dev/null
@@ -1,156 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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 json
-
-from django.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-from openstack_dashboard.dashboards.project.stacks import forms
-from openstack_dashboard.dashboards.project.stacks import mappings
-
-
-INDEX_URL = reverse('horizon:project:stacks:index')
-
-
-class MockResource(object):
- def __init__(self, resource_type, physical_resource_id):
- self.resource_type = resource_type
- self.physical_resource_id = physical_resource_id
-
-
-class MappingsTests(test.TestCase):
-
- def test_mappings(self):
-
- def assertMappingUrl(url, resource_type, physical_resource_id):
- mock = MockResource(resource_type, physical_resource_id)
- mock_url = mappings.resource_to_url(mock)
- self.assertEqual(url, mock_url)
-
- assertMappingUrl(
- '/project/networks/subnets/aaa/detail',
- 'OS::Quantum::Subnet',
- 'aaa')
- assertMappingUrl(
- None,
- 'OS::Quantum::Subnet',
- None)
- assertMappingUrl(
- None,
- None,
- None)
- assertMappingUrl(
- None,
- 'AWS::AutoScaling::LaunchConfiguration',
- 'aaa')
- assertMappingUrl(
- '/project/instances/aaa/',
- 'AWS::EC2::Instance',
- 'aaa')
- assertMappingUrl(
- '/project/containers/aaa/',
- 'OS::Swift::Container',
- 'aaa')
- assertMappingUrl(
- None,
- 'Foo::Bar::Baz',
- 'aaa')
-
- def test_stack_output(self):
- self.assertEqual(u'foo', mappings.stack_output('foo'))
- self.assertEqual(u'', mappings.stack_output(None))
-
- self.assertEqual(
- u'<pre>[\n "one", \n "two", \n "three"\n]</pre>',
- mappings.stack_output(['one', 'two', 'three']))
- self.assertEqual(
- u'<pre>{\n "foo": "bar"\n}</pre>',
- mappings.stack_output({'foo': 'bar'}))
-
- self.assertEqual(
- u'<a href="http://www.example.com/foo" target="_blank">'
- 'http://www.example.com/foo</a>',
- mappings.stack_output('http://www.example.com/foo'))
-
-
-class StackTests(test.TestCase):
-
- @test.create_stubs({api.heat: ('stacks_list',)})
- def test_index(self):
- stacks = self.stacks.list()
-
- api.heat.stacks_list(IsA(http.HttpRequest)) \
- .AndReturn(stacks)
- self.mox.ReplayAll()
-
- res = self.client.get(INDEX_URL)
-
- self.assertTemplateUsed(res, 'project/stacks/index.html')
- self.assertIn('table', res.context)
- resp_stacks = res.context['table'].data
- self.assertEqual(len(resp_stacks), len(stacks))
-
- @test.create_stubs({api.heat: ('stack_create', 'template_validate')})
- def test_launch_stack(self):
- template = self.stack_templates.first()
- stack = self.stacks.first()
-
- api.heat.template_validate(IsA(http.HttpRequest),
- template=template.data) \
- .AndReturn(json.loads(template.validate))
-
- api.heat.stack_create(IsA(http.HttpRequest),
- stack_name=stack.stack_name,
- timeout_mins=60,
- disable_rollback=True,
- template=template.data,
- parameters=IsA(dict),
- password='password')
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:stacks:select_template')
- res = self.client.get(url)
- self.assertTemplateUsed(res, 'project/stacks/select_template.html')
-
- form_data = {'template_source': 'raw',
- 'template_data': template.data,
- 'method': forms.TemplateForm.__name__}
- res = self.client.post(url, form_data)
- self.assertTemplateUsed(res, 'project/stacks/create.html')
-
- url = reverse('horizon:project:stacks:launch')
- form_data = {'template_source': 'raw',
- 'template_data': template.data,
- 'password': 'password',
- 'parameters': template.validate,
- 'stack_name': stack.stack_name,
- "timeout_mins": 60,
- "disable_rollback": True,
- "__param_DBUsername": "admin",
- "__param_LinuxDistribution": "F17",
- "__param_InstanceType": "m1.small",
- "__param_KeyName": "test",
- "__param_DBPassword": "admin",
- "__param_DBRootPassword": "admin",
- "__param_DBName": "wordpress",
- 'method': forms.StackCreateForm.__name__}
- res = self.client.post(url, form_data)
- self.assertRedirectsNoFollow(res, INDEX_URL)
diff --git a/openstack_dashboard/dashboards/project/stacks/urls.py b/openstack_dashboard/dashboards/project/stacks/urls.py
deleted file mode 100644
index 82e0bcf3..00000000
--- a/openstack_dashboard/dashboards/project/stacks/urls.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.stacks.views import CreateStackView
-from openstack_dashboard.dashboards.project.stacks.views import DetailView
-from openstack_dashboard.dashboards.project.stacks.views import IndexView
-from openstack_dashboard.dashboards.project.stacks.views import JSONView
-from openstack_dashboard.dashboards.project.stacks.views import ResourceView
-from openstack_dashboard.dashboards.project.stacks.views \
- import SelectTemplateView
-
-urlpatterns = patterns(
- '',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^select_template$',
- SelectTemplateView.as_view(),
- name='select_template'),
- url(r'^launch$', CreateStackView.as_view(), name='launch'),
- url(r'^stack/(?P<stack_id>[^/]+)/$', DetailView.as_view(), name='detail'),
- url(r'^stack/(?P<stack_id>[^/]+)/(?P<resource_name>[^/]+)/$',
- ResourceView.as_view(), name='resource'),
- url(r'^get_d3_data/(?P<stack_id>[^/]+)/$',
- JSONView.as_view(), name='d3_data'),
-)
diff --git a/openstack_dashboard/dashboards/project/stacks/views.py b/openstack_dashboard/dashboards/project/stacks/views.py
deleted file mode 100644
index 3dfb2906..00000000
--- a/openstack_dashboard/dashboards/project/stacks/views.py
+++ /dev/null
@@ -1,169 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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 json
-import logging
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-from horizon import tabs
-
-from django.core.urlresolvers import reverse
-from django.core.urlresolvers import reverse_lazy
-from django.http import HttpResponse
-from django.utils.translation import ugettext_lazy as _
-from django.views import generic
-
-from openstack_dashboard import api
-
-from openstack_dashboard.dashboards.project.stacks.api import d3_data
-from openstack_dashboard.dashboards.project.stacks.forms import StackCreateForm
-from openstack_dashboard.dashboards.project.stacks.forms import TemplateForm
-from openstack_dashboard.dashboards.project.stacks.tables import StacksTable
-from openstack_dashboard.dashboards.project.stacks.tabs \
- import ResourceDetailTabs
-from openstack_dashboard.dashboards.project.stacks.tabs import StackDetailTabs
-
-
-LOG = logging.getLogger(__name__)
-
-
-class IndexView(tables.DataTableView):
- table_class = StacksTable
- template_name = 'project/stacks/index.html'
-
- def get_data(self):
- request = self.request
- try:
- stacks = api.heat.stacks_list(self.request)
- except:
- exceptions.handle(request, _('Unable to retrieve stack list.'))
- stacks = []
- return stacks
-
-
-class SelectTemplateView(forms.ModalFormView):
- form_class = TemplateForm
- template_name = 'project/stacks/select_template.html'
- success_url = reverse_lazy('horizon:project:stacks:launch')
-
- def get_form_kwargs(self):
- kwargs = super(SelectTemplateView, self).get_form_kwargs()
- kwargs['next_view'] = CreateStackView
- return kwargs
-
-
-class CreateStackView(forms.ModalFormView):
- form_class = StackCreateForm
- template_name = 'project/stacks/create.html'
- success_url = reverse_lazy('horizon:project:stacks:index')
-
- def get_initial(self):
- initial = {}
- if 'template_data' in self.kwargs:
- initial['template_data'] = self.kwargs['template_data']
- if 'template_url' in self.kwargs:
- initial['template_url'] = self.kwargs['template_url']
- if 'parameters' in self.kwargs:
- initial['parameters'] = json.dumps(self.kwargs['parameters'])
- return initial
-
- def get_form_kwargs(self):
- kwargs = super(CreateStackView, self).get_form_kwargs()
- if 'parameters' in self.kwargs:
- kwargs['parameters'] = self.kwargs['parameters']
- else:
- data = json.loads(self.request.POST['parameters'])
- kwargs['parameters'] = data
- return kwargs
-
-
-class DetailView(tabs.TabView):
- tab_group_class = StackDetailTabs
- template_name = 'project/stacks/detail.html'
-
- def get_context_data(self, **kwargs):
- context = super(DetailView, self).get_context_data(**kwargs)
- context["stack"] = self.get_data(self.request)
- return context
-
- def get_data(self, request, **kwargs):
- if not hasattr(self, "_stack"):
- stack_id = kwargs['stack_id']
- try:
- stack = api.heat.stack_get(request, stack_id)
- self._stack = stack
- request.session['stack_id'] = stack.id
- request.session['stack_name'] = stack.stack_name
- except:
- msg = _("Unable to retrieve stack.")
- redirect = reverse('horizon:project:stacks:index')
- exceptions.handle(request, msg, redirect=redirect)
- return self._stack
-
- def get_tabs(self, request, **kwargs):
- stack = self.get_data(request, **kwargs)
- return self.tab_group_class(request, stack=stack, **kwargs)
-
-
-class ResourceView(tabs.TabView):
- tab_group_class = ResourceDetailTabs
- template_name = 'project/stacks/resource.html'
-
- def get_context_data(self, **kwargs):
- context = super(ResourceView, self).get_context_data(**kwargs)
- context["resource"] = self.get_data(self.request, **kwargs)
- context["metadata"] = self.get_metadata(self.request, **kwargs)
- return context
-
- def get_data(self, request, **kwargs):
- if not hasattr(self, "_resource"):
- try:
- resource = api.heat.resource_get(
- request,
- kwargs['stack_id'],
- kwargs['resource_name'])
- self._resource = resource
- except:
- msg = _("Unable to retrieve resource.")
- redirect = reverse('horizon:project:stacks:index')
- exceptions.handle(request, msg, redirect=redirect)
- return self._resource
-
- def get_metadata(self, request, **kwargs):
- if not hasattr(self, "_metadata"):
- try:
- metadata = api.heat.resource_metadata_get(
- request,
- kwargs['stack_id'],
- kwargs['resource_name'])
- self._metadata = json.dumps(metadata, indent=2)
- except:
- msg = _("Unable to retrieve metadata.")
- redirect = reverse('horizon:project:stacks:index')
- exceptions.handle(request, msg, redirect=redirect)
- return self._metadata
-
- def get_tabs(self, request, **kwargs):
- resource = self.get_data(request, **kwargs)
- metadata = self.get_metadata(request, **kwargs)
- return self.tab_group_class(
- request, resource=resource, metadata=metadata, **kwargs)
-
-
-class JSONView(generic.View):
- def get(self, request, stack_id=''):
- return HttpResponse(d3_data(request, stack_id=stack_id),
- content_type="application/json")
diff --git a/openstack_dashboard/dashboards/project/volumes/__init__.py b/openstack_dashboard/dashboards/project/volumes/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/project/volumes/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/project/volumes/forms.py b/openstack_dashboard/dashboards/project/volumes/forms.py
deleted file mode 100644
index 5a5c0d76..00000000
--- a/openstack_dashboard/dashboards/project/volumes/forms.py
+++ /dev/null
@@ -1,353 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-# All rights reserved.
-
-"""
-Views for managing volumes.
-"""
-
-from django.conf import settings
-from django.core.urlresolvers import reverse
-from django.forms import ValidationError
-from django.template.defaultfilters import filesizeformat
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-from horizon.utils.fields import SelectWidget
-from horizon.utils.functions import bytes_to_gigabytes
-from horizon.utils.memoized import memoized
-
-from openstack_dashboard import api
-from openstack_dashboard.api import cinder
-from openstack_dashboard.api import glance
-from openstack_dashboard.dashboards.project.images_and_snapshots.utils \
- import get_available_images
-from openstack_dashboard.dashboards.project.instances.tables \
- import ACTIVE_STATES
-
-
-class CreateForm(forms.SelfHandlingForm):
- name = forms.CharField(max_length="255", label=_("Volume Name"))
- description = forms.CharField(widget=forms.Textarea,
- label=_("Description"), required=False)
- type = forms.ChoiceField(label=_("Type"),
- required=False)
- size = forms.IntegerField(min_value=1, label=_("Size (GB)"))
- encryption = forms.ChoiceField(label=_("Encryption"), required=False)
- volume_source_type = forms.ChoiceField(label=_("Volume Source"),
- required=False)
- snapshot_source = forms.ChoiceField(label=_("Use snapshot as a source"),
- widget=SelectWidget(
- attrs={'class': 'snapshot-selector'},
- data_attrs=('size', 'display_name'),
- transform=lambda x:
- ("%s (%sGB)" % (x.display_name,
- x.size))),
- required=False)
- image_source = forms.ChoiceField(label=_("Use image as a source"),
- widget=SelectWidget(
- attrs={'class': 'image-selector'},
- data_attrs=('size', 'name'),
- transform=lambda x:
- ("%s (%s)" %
- (x.name,
- filesizeformat(x.bytes)))),
- required=False)
-
- def __init__(self, request, *args, **kwargs):
- super(CreateForm, self).__init__(request, *args, **kwargs)
- volume_types = cinder.volume_type_list(request)
- self.fields['type'].choices = [("", "")] + \
- [(type.name, type.name)
- for type in volume_types]
-
- # Hide the volume encryption field if the hypervisor doesn't support it
- # NOTE: as of Grizzly this is not yet supported in Nova so enabling
- # this setting will not do anything useful
- hypervisor_features = getattr(settings,
- "OPENSTACK_HYPERVISOR_FEATURES",
- {})
- can_encrypt_volumes = hypervisor_features.get("can_encrypt_volumes",
- False)
-
- if can_encrypt_volumes:
- # TODO(laura-glendenning) get from api call in future
- encryption_options = {"LUKS": "dmcrypt LUKS"}
- self.fields['encryption'].choices = [("", "")] + \
- [(enc, display) for enc, display in encryption_options.items()]
- else:
- self.fields['encryption'].widget = forms.widgets.HiddenInput()
- self.fields['encryption'].required = False
-
- if ("snapshot_id" in request.GET):
- try:
- snapshot = self.get_snapshot(request,
- request.GET["snapshot_id"])
- self.fields['name'].initial = snapshot.display_name
- self.fields['size'].initial = snapshot.size
- self.fields['snapshot_source'].choices = ((snapshot.id,
- snapshot),)
- try:
- # Set the volume type from the original volume
- orig_volume = cinder.volume_get(request,
- snapshot.volume_id)
- self.fields['type'].initial = orig_volume.volume_type
- except:
- pass
- self.fields['size'].help_text = _('Volume size must be equal '
- 'to or greater than the snapshot size (%sGB)'
- % snapshot.size)
- del self.fields['image_source']
- del self.fields['volume_source_type']
- except:
- exceptions.handle(request,
- _('Unable to load the specified snapshot.'))
- elif ('image_id' in request.GET):
- try:
- image = self.get_image(request,
- request.GET["image_id"])
- image.bytes = image.size
- self.fields['name'].initial = image.name
- self.fields['size'].initial = bytes_to_gigabytes(image.size)
- self.fields['image_source'].choices = ((image.id, image),)
- self.fields['size'].help_text = _('Volume size must be equal '
- 'to or greater than the image size (%s)'
- % filesizeformat(image.size))
- del self.fields['snapshot_source']
- del self.fields['volume_source_type']
- except:
- msg = _('Unable to load the specified image. %s')
- exceptions.handle(request, msg % request.GET['image_id'])
- else:
- source_type_choices = []
-
- try:
- snapshots = cinder.volume_snapshot_list(request)
- if snapshots:
- source_type_choices.append(("snapshot_source",
- _("Snapshot")))
- choices = [('', _("Choose a snapshot"))] + \
- [(s.id, s) for s in snapshots]
- self.fields['snapshot_source'].choices = choices
- else:
- del self.fields['snapshot_source']
- except:
- exceptions.handle(request, _("Unable to retrieve "
- "volume snapshots."))
-
- images = get_available_images(request,
- request.user.tenant_id)
- if images:
- source_type_choices.append(("image_source", _("Image")))
- choices = [('', _("Choose an image"))]
- for image in images:
- image.bytes = image.size
- image.size = bytes_to_gigabytes(image.bytes)
- choices.append((image.id, image))
- self.fields['image_source'].choices = choices
- else:
- del self.fields['image_source']
-
- if source_type_choices:
- choices = ([('no_source_type',
- _("No source, empty volume."))] +
- source_type_choices)
- self.fields['volume_source_type'].choices = choices
- else:
- del self.fields['volume_source_type']
-
- def handle(self, request, data):
- try:
- # FIXME(johnp): cinderclient currently returns a useless
- # error message when the quota is exceeded when trying to create
- # a volume, so we need to check for that scenario here before we
- # send it off to try and create.
- usages = cinder.tenant_absolute_limits(self.request)
- volumes = cinder.volume_list(self.request)
- total_size = sum([getattr(volume, 'size', 0) for volume
- in volumes])
- usages['gigabytesUsed'] = total_size
- usages['volumesUsed'] = len(volumes)
- availableGB = usages['maxTotalVolumeGigabytes'] -\
- usages['gigabytesUsed']
- availableVol = usages['maxTotalVolumes'] - usages['volumesUsed']
-
- snapshot_id = None
- image_id = None
- source_type = data.get('volume_source_type', None)
- if (data.get("snapshot_source", None) and
- source_type in [None, 'snapshot_source']):
- # Create from Snapshot
- snapshot = self.get_snapshot(request,
- data["snapshot_source"])
- snapshot_id = snapshot.id
- if (data['size'] < snapshot.size):
- error_message = _('The volume size cannot be less than '
- 'the snapshot size (%sGB)' %
- snapshot.size)
- raise ValidationError(error_message)
- elif (data.get("image_source", None) and
- source_type in [None, 'image_source']):
- # Create from Snapshot
- image = self.get_image(request,
- data["image_source"])
- image_id = image.id
- image_size = bytes_to_gigabytes(image.size)
- if (data['size'] < image_size):
- error_message = _('The volume size cannot be less than '
- 'the image size (%s)' %
- filesizeformat(image.size))
- raise ValidationError(error_message)
- else:
- if type(data['size']) is str:
- data['size'] = int(data['size'])
-
- if availableGB < data['size']:
- error_message = _('A volume of %(req)iGB cannot be created as '
- 'you only have %(avail)iGB of your quota '
- 'available.')
- params = {'req': data['size'],
- 'avail': availableGB}
- raise ValidationError(error_message % params)
- elif availableVol <= 0:
- error_message = _('You are already using all of your available'
- ' volumes.')
- raise ValidationError(error_message)
-
- metadata = {}
-
- if data['encryption']:
- metadata['encryption'] = data['encryption']
-
- volume = cinder.volume_create(request,
- data['size'],
- data['name'],
- data['description'],
- data['type'],
- snapshot_id=snapshot_id,
- image_id=image_id,
- metadata=metadata)
- message = _('Creating volume "%s"') % data['name']
- messages.info(request, message)
- return volume
- except ValidationError as e:
- self.api_error(e.messages[0])
- return False
- except:
- exceptions.handle(request, ignore=True)
- self.api_error(_("Unable to create volume."))
- return False
-
- @memoized
- def get_snapshot(self, request, id):
- return cinder.volume_snapshot_get(request, id)
-
- @memoized
- def get_image(self, request, id):
- return glance.image_get(request, id)
-
-
-class AttachForm(forms.SelfHandlingForm):
- instance = forms.ChoiceField(label=_("Attach to Instance"),
- help_text=_("Select an instance to "
- "attach to."))
- device = forms.CharField(label=_("Device Name"))
-
- def __init__(self, *args, **kwargs):
- super(AttachForm, self).__init__(*args, **kwargs)
-
- # Hide the device field if the hypervisor doesn't support it.
- hypervisor_features = getattr(settings,
- "OPENSTACK_HYPERVISOR_FEATURES",
- {})
- can_set_mount_point = hypervisor_features.get("can_set_mount_point",
- True)
- if not can_set_mount_point:
- self.fields['device'].widget = forms.widgets.HiddenInput()
- self.fields['device'].required = False
-
- # populate volume_id
- volume = kwargs.get('initial', {}).get("volume", None)
- if volume:
- volume_id = volume.id
- else:
- volume_id = None
- self.fields['volume_id'] = forms.CharField(widget=forms.HiddenInput(),
- initial=volume_id)
-
- # Populate instance choices
- instance_list = kwargs.get('initial', {}).get('instances', [])
- instances = []
- for instance in instance_list:
- if instance.status in ACTIVE_STATES and \
- not any(instance.id == att["server_id"]
- for att in volume.attachments):
- instances.append((instance.id, '%s (%s)' % (instance.name,
- instance.id)))
- if instances:
- instances.insert(0, ("", _("Select an instance")))
- else:
- instances = (("", _("No instances available")),)
- self.fields['instance'].choices = instances
-
- def handle(self, request, data):
- instance_choices = dict(self.fields['instance'].choices)
- instance_name = instance_choices.get(data['instance'],
- _("Unknown instance (None)"))
- # The name of the instance in the choices list has the ID appended to
- # it, so let's slice that off...
- instance_name = instance_name.rsplit(" (")[0]
- try:
- attach = api.nova.instance_volume_attach(request,
- data['volume_id'],
- data['instance'],
- data.get('device', ''))
- volume = cinder.volume_get(request, data['volume_id'])
- if not volume.display_name:
- volume_name = volume.id
- else:
- volume_name = volume.display_name
- message = _('Attaching volume %(vol)s to instance '
- '%(inst)s on %(dev)s.') % {"vol": volume_name,
- "inst": instance_name,
- "dev": attach.device}
- messages.info(request, message)
- return True
- except:
- redirect = reverse("horizon:project:volumes:index")
- exceptions.handle(request,
- _('Unable to attach volume.'),
- redirect=redirect)
-
-
-class CreateSnapshotForm(forms.SelfHandlingForm):
- name = forms.CharField(max_length="255", label=_("Snapshot Name"))
- description = forms.CharField(widget=forms.Textarea,
- label=_("Description"), required=False)
-
- def __init__(self, request, *args, **kwargs):
- super(CreateSnapshotForm, self).__init__(request, *args, **kwargs)
-
- # populate volume_id
- volume_id = kwargs.get('initial', {}).get('volume_id', [])
- self.fields['volume_id'] = forms.CharField(widget=forms.HiddenInput(),
- initial=volume_id)
-
- def handle(self, request, data):
- try:
- snapshot = cinder.volume_snapshot_create(request,
- data['volume_id'],
- data['name'],
- data['description'])
-
- message = _('Creating volume snapshot "%s"') % data['name']
- messages.info(request, message)
- return snapshot
- except:
- redirect = reverse("horizon:project:images_and_snapshots:index")
- exceptions.handle(request,
- _('Unable to create volume snapshot.'),
- redirect=redirect)
diff --git a/openstack_dashboard/dashboards/project/volumes/panel.py b/openstack_dashboard/dashboards/project/volumes/panel.py
deleted file mode 100644
index 351e63cf..00000000
--- a/openstack_dashboard/dashboards/project/volumes/panel.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.project import dashboard
-
-
-class Volumes(horizon.Panel):
- name = _("Volumes")
- slug = 'volumes'
- permissions = ('openstack.services.volume',)
-
-
-dashboard.Project.register(Volumes)
diff --git a/openstack_dashboard/dashboards/project/volumes/tables.py b/openstack_dashboard/dashboards/project/volumes/tables.py
deleted file mode 100644
index 7a61ed0c..00000000
--- a/openstack_dashboard/dashboards/project/volumes/tables.py
+++ /dev/null
@@ -1,250 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-
-from django.core.urlresolvers import NoReverseMatch
-from django.core.urlresolvers import reverse
-from django.template.defaultfilters import title
-from django.utils.html import strip_tags
-from django.utils import safestring
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tables
-
-from openstack_dashboard import api
-from openstack_dashboard.api import cinder
-
-
-LOG = logging.getLogger(__name__)
-
-DELETABLE_STATES = ("available", "error")
-
-
-class DeleteVolume(tables.DeleteAction):
- data_type_singular = _("Volume")
- data_type_plural = _("Volumes")
- action_past = _("Scheduled deletion of")
-
- def delete(self, request, obj_id):
- obj = self.table.get_object_by_id(obj_id)
- name = self.table.get_object_display(obj)
- try:
- cinder.volume_delete(request, obj_id)
- except:
- msg = _('Unable to delete volume "%s". One or more snapshots '
- 'depend on it.')
- exceptions.check_message(["snapshots", "dependent"], msg % name)
- raise
-
- def allowed(self, request, volume=None):
- if volume:
- return volume.status in DELETABLE_STATES
- return True
-
-
-class CreateVolume(tables.LinkAction):
- name = "create"
- verbose_name = _("Create Volume")
- url = "horizon:project:volumes:create"
- classes = ("ajax-modal", "btn-create")
-
-
-class EditAttachments(tables.LinkAction):
- name = "attachments"
- verbose_name = _("Edit Attachments")
- url = "horizon:project:volumes:attach"
- classes = ("ajax-modal", "btn-edit")
-
- def allowed(self, request, volume=None):
- return volume.status in ("available", "in-use")
-
-
-class CreateSnapshot(tables.LinkAction):
- name = "snapshots"
- verbose_name = _("Create Snapshot")
- url = "horizon:project:volumes:create_snapshot"
- classes = ("ajax-modal", "btn-camera")
-
- def allowed(self, request, volume=None):
- return volume.status == "available"
-
-
-class UpdateRow(tables.Row):
- ajax = True
-
- def get_data(self, request, volume_id):
- volume = cinder.volume_get(request, volume_id)
- if not volume.display_name:
- volume.display_name = volume_id
- return volume
-
-
-def get_size(volume):
- return _("%sGB") % volume.size
-
-
-def get_attachment_name(request, attachment):
- server_id = attachment.get("server_id", None)
- if "instance" in attachment and attachment['instance']:
- name = attachment["instance"].name
- else:
- try:
- server = api.nova.server_get(request, server_id)
- name = server.name
- except:
- name = None
- exceptions.handle(request, _("Unable to retrieve "
- "attachment information."))
- try:
- url = reverse("horizon:project:instances:detail", args=(server_id,))
- instance = '<a href="%s">%s</a>' % (url, name)
- except NoReverseMatch:
- instance = name
- return instance
-
-
-class AttachmentColumn(tables.Column):
- """
- Customized column class that does complex processing on the attachments
- for a volume instance.
- """
- def get_raw_data(self, volume):
- request = self.table.request
- link = _('Attached to %(instance)s on %(dev)s')
- attachments = []
- # Filter out "empty" attachments which the client returns...
- for attachment in [att for att in volume.attachments if att]:
- # When a volume is attached it may return the server_id
- # without the server name...
- instance = get_attachment_name(request, attachment)
- vals = {"instance": instance,
- "dev": attachment["device"]}
- attachments.append(link % vals)
- return safestring.mark_safe(", ".join(attachments))
-
-
-def get_volume_type(volume):
- return volume.volume_type if volume.volume_type != "None" else None
-
-
-class VolumesTableBase(tables.DataTable):
- STATUS_CHOICES = (
- ("in-use", True),
- ("available", True),
- ("creating", None),
- ("error", False),
- )
- name = tables.Column("display_name",
- verbose_name=_("Name"),
- link="horizon:project:volumes:detail")
- description = tables.Column("display_description",
- verbose_name=_("Description"),
- truncate=40)
- size = tables.Column(get_size,
- verbose_name=_("Size"),
- attrs={'data-type': 'size'})
- status = tables.Column("status",
- filters=(title,),
- verbose_name=_("Status"),
- status=True,
- status_choices=STATUS_CHOICES)
-
- def get_object_display(self, obj):
- return obj.display_name
-
-
-class VolumesFilterAction(tables.FilterAction):
-
- def filter(self, table, volumes, filter_string):
- """ Naive case-insensitive search. """
- q = filter_string.lower()
- return [volume for volume in volumes
- if q in volume.display_name.lower()]
-
-
-class VolumesTable(VolumesTableBase):
- name = tables.Column("display_name",
- verbose_name=_("Name"),
- link="horizon:project:volumes:detail")
- volume_type = tables.Column(get_volume_type,
- verbose_name=_("Type"),
- empty_value="-")
- attachments = AttachmentColumn("attachments",
- verbose_name=_("Attached To"))
-
- class Meta:
- name = "volumes"
- verbose_name = _("Volumes")
- status_columns = ["status"]
- row_class = UpdateRow
- table_actions = (CreateVolume, DeleteVolume, VolumesFilterAction)
- row_actions = (EditAttachments, CreateSnapshot, DeleteVolume)
-
-
-class DetachVolume(tables.BatchAction):
- name = "detach"
- action_present = _("Detach")
- action_past = _("Detaching") # This action is asynchronous.
- data_type_singular = _("Volume")
- data_type_plural = _("Volumes")
- classes = ('btn-danger', 'btn-detach')
-
- def action(self, request, obj_id):
- attachment = self.table.get_object_by_id(obj_id)
- api.nova.instance_volume_detach(request,
- attachment.get('server_id', None),
- obj_id)
-
- def get_success_url(self, request):
- return reverse('horizon:project:volumes:index')
-
-
-class AttachedInstanceColumn(tables.Column):
- """
- Customized column class that does complex processing on the attachments
- for a volume instance.
- """
- def get_raw_data(self, attachment):
- request = self.table.request
- return safestring.mark_safe(get_attachment_name(request, attachment))
-
-
-class AttachmentsTable(tables.DataTable):
- instance = AttachedInstanceColumn(get_attachment_name,
- verbose_name=_("Instance"))
- device = tables.Column("device")
-
- def get_object_id(self, obj):
- return obj['id']
-
- def get_object_display(self, attachment):
- instance_name = get_attachment_name(self.request, attachment)
- vals = {"dev": attachment['device'],
- "instance_name": strip_tags(instance_name)}
- return _("%(dev)s on instance %(instance_name)s") % vals
-
- def get_object_by_id(self, obj_id):
- for obj in self.data:
- if self.get_object_id(obj) == obj_id:
- return obj
- raise ValueError('No match found for the id "%s".' % obj_id)
-
- class Meta:
- name = "attachments"
- table_actions = (DetachVolume,)
- row_actions = (DetachVolume,)
diff --git a/openstack_dashboard/dashboards/project/volumes/tabs.py b/openstack_dashboard/dashboards/project/volumes/tabs.py
deleted file mode 100644
index b266342b..00000000
--- a/openstack_dashboard/dashboards/project/volumes/tabs.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import exceptions
-from horizon import tabs
-
-from openstack_dashboard.api import cinder
-from openstack_dashboard.api import nova
-
-
-class OverviewTab(tabs.Tab):
- name = _("Overview")
- slug = "overview"
- template_name = ("project/volumes/"
- "_detail_overview.html")
-
- def get_context_data(self, request):
- volume_id = self.tab_group.kwargs['volume_id']
- try:
- volume = cinder.volume_get(request, volume_id)
- for att in volume.attachments:
- att['instance'] = nova.server_get(request, att['server_id'])
- except:
- redirect = reverse('horizon:project:volumes:index')
- exceptions.handle(self.request,
- _('Unable to retrieve volume details.'),
- redirect=redirect)
- return {'volume': volume}
-
-
-class VolumeDetailTabs(tabs.TabGroup):
- slug = "volume_details"
- tabs = (OverviewTab,)
diff --git a/openstack_dashboard/dashboards/project/volumes/templates/volumes/_attach.html b/openstack_dashboard/dashboards/project/volumes/templates/volumes/_attach.html
deleted file mode 100644
index 33db6f44..00000000
--- a/openstack_dashboard/dashboards/project/volumes/templates/volumes/_attach.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}attach_volume_form{% endblock %}
-{% block form_action %}{% url 'horizon:project:volumes:attach' volume.id %}{% endblock %}
-{% block form_class %}{{ block.super }} horizontal {% if show_attach %}split_half{% else %} no_split{% endif %}{% endblock %}
-
-{% block modal_id %}attach_volume_modal{% endblock %}
-{% block modal-header %}{% trans "Manage Volume Attachments" %}{% endblock %}
-
-{% block modal-body %}
- {% if show_attach %}
- <h3>{% trans "Attach To Instance" %}</h3>
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
- {% endif %}
-{% endblock %}
-
-{% block modal-footer %}
- {% if show_attach %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Attach Volume" %}" />
- {% endif %}
- <a href="{% url 'horizon:project:volumes:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/volumes/templates/volumes/_create.html b/openstack_dashboard/dashboards/project/volumes/templates/volumes/_create.html
deleted file mode 100644
index 8966bf85..00000000
--- a/openstack_dashboard/dashboards/project/volumes/templates/volumes/_create.html
+++ /dev/null
@@ -1,26 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}{% endblock %}
-{% block form_action %}{% url 'horizon:project:volumes:create' %}?{{ request.GET.urlencode }}{% endblock %}
-
-{% block modal_id %}create_volume_modal{% endblock %}
-{% block modal-header %}{% trans "Create Volume" %}{% endblock %}
-
-{% block modal-body %}
- <div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
- </div>
-
- <div class="right quota-dynamic">
- {% include "project/volumes/_limits.html" with usages=usages %}
- </div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Volume" %}" />
- <a href="{% url 'horizon:project:volumes:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/volumes/templates/volumes/_create_snapshot.html b/openstack_dashboard/dashboards/project/volumes/templates/volumes/_create_snapshot.html
deleted file mode 100644
index 97c97bff..00000000
--- a/openstack_dashboard/dashboards/project/volumes/templates/volumes/_create_snapshot.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}{% endblock %}
-{% block form_action %}{% url 'horizon:project:volumes:create_snapshot' volume_id %}{% endblock %}
-
-{% block modal_id %}create_volume_snapshot_modal{% endblock %}
-{% block modal-header %}{% trans "Create Volume Snapshot" %}{% endblock %}
-
-{% block modal-body %}
- <div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
- </div>
- <div class="right quota-dynamic">
- {% include "project/volumes/_quota.html" with usages=usages snapshot_quota=True %}
- </div>
-{% endblock %}
-
-{% block modal-footer %}
- <input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Volume Snapshot" %}" />
- <a href="{% url 'horizon:project:volumes:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/volumes/templates/volumes/_detail_overview.html b/openstack_dashboard/dashboards/project/volumes/templates/volumes/_detail_overview.html
deleted file mode 100644
index 0a6d314f..00000000
--- a/openstack_dashboard/dashboards/project/volumes/templates/volumes/_detail_overview.html
+++ /dev/null
@@ -1,61 +0,0 @@
-{% load i18n sizeformat parse_date %}
-{% load url from future %}
-
-<h3>{% trans "Volume Overview" %}: {{volume.display_name }}</h3>
-
-<div class="info row-fluid detail">
- <h4>{% trans "Info" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Name" %}</dt>
- <dd>{{ volume.display_name }}</dd>
- <dt>{% trans "ID" %}</dt>
- <dd>{{ volume.id }}</dd>
- {% if volume.display_description %}
- <dt>{% trans "Description" %}</dt>
- <dd>{{ volume.display_description }}</dd>
- {% endif %}
- <dt>{% trans "Status" %}</dt>
- <dd>{{ volume.status|capfirst }}</dd>
- </dl>
-</div>
-
-<div class="specs row-fluid detail">
- <h4>{% trans "Specs" %}</h4>
- <hr class="header_rule">
- <dl>
- <dt>{% trans "Size" %}</dt>
- <dd>{{ volume.size }} {% trans "GB" %}</dd>
- <dt>{% trans "Created" %}</dt>
- <dd>{{ volume.created_at|parse_date }}</dd>
- </dl>
-</div>
-
-<div class="status row-fluid detail">
- <h4>{% trans "Attachments" %}</h4>
- <hr class="header_rule">
- <dl>
- {% for attachment in volume.attachments %}
- <dt>{% trans "Attached To" %}</dt>
- <dd>
- {% url 'horizon:project:instances:detail' attachment.server_id as instance_url%}
- <a href="{{ instance_url }}">{{ attachment.instance.name }}</a>
- <span> {% trans "on" %} {{ attachment.device }}</span>
- </dd>
- {% empty %}
- <dt>{% trans "Attached To" %}</dt>
- <dd><em>{% trans "Not attached" %}</em></dd>
- {% endfor %}
- </dl>
-</div>
-
-<div class="status row-fluid detail">
- <h4>{% trans "Metadata" %}</h4>
- <hr class="header_rule">
- <dl>
- {% for key, value in volume.metadata.items %}
- <dt>{{ key }}</dt>
- <dd>{{ value }}</dd>
- {% endfor %}
- </dl>
-</div>
diff --git a/openstack_dashboard/dashboards/project/volumes/templates/volumes/_limits.html b/openstack_dashboard/dashboards/project/volumes/templates/volumes/_limits.html
deleted file mode 100644
index b2fbdbd0..00000000
--- a/openstack_dashboard/dashboards/project/volumes/templates/volumes/_limits.html
+++ /dev/null
@@ -1,34 +0,0 @@
-{% load i18n horizon humanize %}
-
-<h3>{% trans "Description" %}:</h3>
-
-<p>{% trans "Volumes are block devices that can be attached to instances." %}</p>
-
-<h3>{% trans "Volume Limits" %}</h3>
-
-<div class="quota_title clearfix">
- <strong>{% trans "Total Gigabytes" %} <span>({{ usages.gigabytesUsed|intcomma }} {% trans "GB" %})</span></strong>
- <p>{{ usages.maxTotalVolumeGigabytes|quota:_("GB")|intcomma }}</p>
-</div>
-
-<div id="quota_size" data-progress-indicator-for="id_size" data-quota-limit="{{ usages.maxTotalVolumeGigabytes }}" data-quota-used="{{ usages.gigabytesUsed }}" class="quota_bar">
-</div>
-
-<div class="quota_title clearfix">
- <strong>{% trans "Number of Volumes" %} <span>({{ usages.volumesUsed|intcomma }})</span></strong>
- <p>{{ usages.maxTotalVolumes|quota|intcomma }}</p>
-</div>
-
-<div id="quota_volumes" data-progress-indicator-step-by="1" data-quota-limit="{{ usages.maxTotalVolumes}}" data-quota-used="{{ usages.volumesUsed }}" class="quota_bar">
-</div>
-
-
-<script type="text/javascript" charset="utf-8">
- if(typeof horizon.Quota !== 'undefined') {
- horizon.Quota.init();
- } else {
- addHorizonLoadEvent(function() {
- horizon.Quota.init();
- });
- }
-</script>
diff --git a/openstack_dashboard/dashboards/project/volumes/templates/volumes/attach.html b/openstack_dashboard/dashboards/project/volumes/templates/volumes/attach.html
deleted file mode 100644
index 4b4dad86..00000000
--- a/openstack_dashboard/dashboards/project/volumes/templates/volumes/attach.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Manage Volume Attachments" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Manage Volume Attachments") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/volumes/_attach.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/volumes/templates/volumes/create.html b/openstack_dashboard/dashboards/project/volumes/templates/volumes/create.html
deleted file mode 100644
index 08710c7b..00000000
--- a/openstack_dashboard/dashboards/project/volumes/templates/volumes/create.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Volume" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create a Volume") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/volumes/_create.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/volumes/templates/volumes/create_snapshot.html b/openstack_dashboard/dashboards/project/volumes/templates/volumes/create_snapshot.html
deleted file mode 100644
index 4aa6562e..00000000
--- a/openstack_dashboard/dashboards/project/volumes/templates/volumes/create_snapshot.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Create Volume Snapshot" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Create a Volume Snapshot") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include 'project/volumes/_create_snapshot.html' %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/volumes/templates/volumes/detail.html b/openstack_dashboard/dashboards/project/volumes/templates/volumes/detail.html
deleted file mode 100644
index 9dbbd408..00000000
--- a/openstack_dashboard/dashboards/project/volumes/templates/volumes/detail.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Volume Details" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Volume Detail") %}
-{% endblock page_header %}
-
-{% block main %}
-<div class="row-fluid">
- <div class="span12">
- {{ tab_group.render }}
- </div>
-</div>
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/volumes/templates/volumes/index.html b/openstack_dashboard/dashboards/project/volumes/templates/volumes/index.html
deleted file mode 100644
index 201e7742..00000000
--- a/openstack_dashboard/dashboards/project/volumes/templates/volumes/index.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Volumes" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Volumes") %}
-{% endblock page_header %}
-
-{% block main %}
- {{ table.render }}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/project/volumes/tests.py b/openstack_dashboard/dashboards/project/volumes/tests.py
deleted file mode 100644
index c474b4ab..00000000
--- a/openstack_dashboard/dashboards/project/volumes/tests.py
+++ /dev/null
@@ -1,782 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf import settings
-from django.core.urlresolvers import reverse
-from django.forms import widgets
-from django import http
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.api import cinder
-from openstack_dashboard.test import helpers as test
-
-
-class VolumeViewTests(test.TestCase):
- @test.create_stubs({cinder: ('volume_create',
- 'volume_snapshot_list',
- 'volume_type_list',
- 'tenant_absolute_limits',
- 'volume_list',),
- api.glance: ('image_list_detailed',)})
- def test_create_volume(self):
- volume = self.volumes.first()
- volume_type = self.volume_types.first()
- usage_limit = {'maxTotalVolumeGigabytes': 250,
- 'gigabytesUsed': 20,
- 'maxTotalVolumes': 6}
- formData = {'name': u'A Volume I Am Making',
- 'description': u'This is a volume I am making for a test.',
- 'method': u'CreateForm',
- 'type': volume_type.name,
- 'size': 50,
- 'snapshot_source': ''}
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_snapshots.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- cinder.volume_create(IsA(http.HttpRequest),
- formData['size'],
- formData['name'],
- formData['description'],
- formData['type'],
- metadata={},
- snapshot_id=None,
- image_id=None).AndReturn(volume)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:create')
- res = self.client.post(url, formData)
-
- redirect_url = reverse('horizon:project:volumes:index')
- self.assertRedirectsNoFollow(res, redirect_url)
-
- @test.create_stubs({cinder: ('volume_create',
- 'volume_snapshot_list',
- 'volume_type_list',
- 'tenant_absolute_limits',
- 'volume_list',),
- api.glance: ('image_list_detailed',)})
- def test_create_volume_dropdown(self):
- volume = self.volumes.first()
- usage_limit = {'maxTotalVolumeGigabytes': 250,
- 'maxTotalVolumes': 6}
- formData = {'name': u'A Volume I Am Making',
- 'description': u'This is a volume I am making for a test.',
- 'method': u'CreateForm',
- 'size': 50,
- 'type': '',
- 'volume_source_type': 'no_source_type',
- 'snapshot_source': self.volume_snapshots.first().id,
- 'image_source': self.images.first().id}
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_snapshots.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
- cinder.volume_create(IsA(http.HttpRequest),
- formData['size'],
- formData['name'],
- formData['description'],
- '',
- metadata={},
- snapshot_id=None,
- image_id=None).\
- AndReturn(volume)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:create')
- res = self.client.post(url, formData)
-
- redirect_url = reverse('horizon:project:volumes:index')
- self.assertRedirectsNoFollow(res, redirect_url)
-
- @test.create_stubs({cinder: ('volume_create',
- 'volume_snapshot_get',
- 'volume_get',
- 'volume_type_list',
- 'tenant_absolute_limits',
- 'volume_list',)})
- def test_create_volume_from_snapshot(self):
- volume = self.volumes.first()
- usage_limit = {'maxTotalVolumeGigabytes': 250,
- 'maxTotalVolumes': 6}
- snapshot = self.volume_snapshots.first()
- formData = {'name': u'A Volume I Am Making',
- 'description': u'This is a volume I am making for a test.',
- 'method': u'CreateForm',
- 'size': 50,
- 'type': '',
- 'snapshot_source': snapshot.id}
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
- cinder.volume_snapshot_get(IsA(http.HttpRequest),
- str(snapshot.id)).AndReturn(snapshot)
- cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\
- AndReturn(self.volumes.first())
- cinder.volume_create(IsA(http.HttpRequest),
- formData['size'],
- formData['name'],
- formData['description'],
- '',
- metadata={},
- snapshot_id=snapshot.id,
- image_id=None).\
- AndReturn(volume)
- self.mox.ReplayAll()
-
- # get snapshot from url
- url = reverse('horizon:project:volumes:create')
- res = self.client.post("?".join([url,
- "snapshot_id=" + str(snapshot.id)]),
- formData)
-
- redirect_url = reverse('horizon:project:volumes:index')
- self.assertRedirectsNoFollow(res, redirect_url)
-
- @test.create_stubs({cinder: ('volume_create',
- 'volume_snapshot_list',
- 'volume_snapshot_get',
- 'volume_get',
- 'volume_type_list',
- 'tenant_absolute_limits',
- 'volume_list',),
- api.glance: ('image_list_detailed',)})
- def test_create_volume_from_snapshot_dropdown(self):
- volume = self.volumes.first()
- usage_limit = {'maxTotalVolumeGigabytes': 250,
- 'maxTotalVolumes': 6}
- snapshot = self.volume_snapshots.first()
- formData = {'name': u'A Volume I Am Making',
- 'description': u'This is a volume I am making for a test.',
- 'method': u'CreateForm',
- 'size': 50,
- 'type': '',
- 'volume_source_type': 'snapshot_source',
- 'snapshot_source': snapshot.id}
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_snapshots.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
- cinder.volume_snapshot_get(IsA(http.HttpRequest),
- str(snapshot.id)).AndReturn(snapshot)
- cinder.volume_create(IsA(http.HttpRequest),
- formData['size'],
- formData['name'],
- formData['description'],
- '',
- metadata={},
- snapshot_id=snapshot.id,
- image_id=None).\
- AndReturn(volume)
-
- self.mox.ReplayAll()
-
- # get snapshot from dropdown list
- url = reverse('horizon:project:volumes:create')
- res = self.client.post(url, formData)
-
- redirect_url = reverse('horizon:project:volumes:index')
- self.assertRedirectsNoFollow(res, redirect_url)
-
- @test.create_stubs({cinder: ('volume_snapshot_get',
- 'volume_type_list',
- 'volume_get',
- 'tenant_absolute_limits',
- 'volume_list',),
- api.glance: ('image_list_detailed',)})
- def test_create_volume_from_snapshot_invalid_size(self):
- usage_limit = {'maxTotalVolumeGigabytes': 100,
- 'maxTotalVolumes': 6}
- snapshot = self.volume_snapshots.first()
- formData = {'name': u'A Volume I Am Making',
- 'description': u'This is a volume I am making for a test.',
- 'method': u'CreateForm',
- 'size': 20, 'snapshot_source': snapshot.id}
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
- cinder.volume_snapshot_get(IsA(http.HttpRequest),
- str(snapshot.id)).AndReturn(snapshot)
- cinder.volume_get(IsA(http.HttpRequest), snapshot.volume_id).\
- AndReturn(self.volumes.first())
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:create')
- res = self.client.post("?".join([url,
- "snapshot_id=" + str(snapshot.id)]),
- formData, follow=True)
- self.assertEqual(res.redirect_chain, [])
- self.assertFormError(res, 'form', None,
- "The volume size cannot be less than the "
- "snapshot size (40GB)")
-
- @test.create_stubs({cinder: ('volume_create',
- 'volume_type_list',
- 'tenant_absolute_limits',
- 'volume_list',),
- api.glance: ('image_get',)})
- def test_create_volume_from_image(self):
- volume = self.volumes.first()
- usage_limit = {'maxTotalVolumeGigabytes': 200,
- 'maxTotalVolumes': 6}
- image = self.images.first()
- formData = {'name': u'A Volume I Am Making',
- 'description': u'This is a volume I am making for a test.',
- 'method': u'CreateForm',
- 'size': 40,
- 'type': '',
- 'image_source': image.id}
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
- api.glance.image_get(IsA(http.HttpRequest),
- str(image.id)).AndReturn(image)
- cinder.volume_create(IsA(http.HttpRequest),
- formData['size'],
- formData['name'],
- formData['description'],
- '',
- metadata={},
- snapshot_id=None,
- image_id=image.id).\
- AndReturn(volume)
-
- self.mox.ReplayAll()
-
- # get image from url
- url = reverse('horizon:project:volumes:create')
- res = self.client.post("?".join([url,
- "image_id=" + str(image.id)]),
- formData)
-
- redirect_url = reverse('horizon:project:volumes:index')
- self.assertRedirectsNoFollow(res, redirect_url)
-
- @test.create_stubs({cinder: ('volume_create',
- 'volume_type_list',
- 'volume_snapshot_list',
- 'tenant_absolute_limits',
- 'volume_list',),
- api.glance: ('image_get',
- 'image_list_detailed')})
- def test_create_volume_from_image_dropdown(self):
- volume = self.volumes.first()
- usage_limit = {'maxTotalVolumeGigabytes': 200,
- 'maxTotalVolumes': 6}
- image = self.images.first()
- formData = {'name': u'A Volume I Am Making',
- 'description': u'This is a volume I am making for a test.',
- 'method': u'CreateForm',
- 'size': 30,
- 'type': '',
- 'volume_source_type': 'image_source',
- 'snapshot_source': self.volume_snapshots.first().id,
- 'image_source': image.id}
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_snapshots.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)) \
- .AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- api.glance.image_get(IsA(http.HttpRequest),
- str(image.id)).AndReturn(image)
- cinder.volume_create(IsA(http.HttpRequest),
- formData['size'],
- formData['name'],
- formData['description'],
- '',
- metadata={},
- snapshot_id=None,
- image_id=image.id).\
- AndReturn(volume)
-
- self.mox.ReplayAll()
-
- # get image from dropdown list
- url = reverse('horizon:project:volumes:create')
- res = self.client.post(url, formData)
-
- redirect_url = reverse('horizon:project:volumes:index')
- self.assertRedirectsNoFollow(res, redirect_url)
-
- @test.create_stubs({cinder: ('volume_type_list', 'tenant_absolute_limits',
- 'volume_list',),
- api.glance: ('image_get',
- 'image_list_detailed')})
- def test_create_volume_from_image_invalid_size(self):
- usage_limit = {'maxTotalVolumeGigabytes': 100,
- 'maxTotalVolumes': 6}
- image = self.images.first()
- formData = {'name': u'A Volume I Am Making',
- 'description': u'This is a volume I am making for a test.',
- 'method': u'CreateForm',
- 'size': 1, 'image_source': image.id}
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
- api.glance.image_get(IsA(http.HttpRequest),
- str(image.id)).AndReturn(image)
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:create')
- res = self.client.post("?".join([url,
- "image_id=" + str(image.id)]),
- formData, follow=True)
- self.assertEqual(res.redirect_chain, [])
- self.assertFormError(res, 'form', None,
- "The volume size cannot be less than the "
- "image size (20.0 GB)")
-
- @test.create_stubs({cinder: ('volume_snapshot_list', 'volume_type_list',
- 'tenant_absolute_limits', 'volume_list',),
- api.glance: ('image_list_detailed',)})
- def test_create_volume_gb_used_over_alloted_quota(self):
- usage_limit = {'maxTotalVolumeGigabytes': 100,
- 'maxTotalVolumes': 6}
- formData = {'name': u'This Volume Is Huge!',
- 'description': u'This is a volume that is just too big!',
- 'method': u'CreateForm',
- 'size': 5000}
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_snapshots.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:create')
- res = self.client.post(url, formData)
-
- expected_error = [u'A volume of 5000GB cannot be created as you only'
- ' have 20GB of your quota available.']
- self.assertEqual(res.context['form'].errors['__all__'], expected_error)
-
- @test.create_stubs({cinder: ('volume_snapshot_list', 'volume_type_list',
- 'tenant_absolute_limits', 'volume_list',),
- api.glance: ('image_list_detailed',)})
- def test_create_volume_number_over_alloted_quota(self):
- usage_limit = {'maxTotalVolumeGigabytes': 100,
- 'maxTotalVolumes': len(self.volumes.list())}
- formData = {'name': u'Too Many...',
- 'description': u'We have no volumes left!',
- 'method': u'CreateForm',
- 'size': 10}
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_snapshots.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:create')
- res = self.client.post(url, formData)
-
- expected_error = [u'You are already using all of your available'
- ' volumes.']
- self.assertEqual(res.context['form'].errors['__all__'], expected_error)
-
- @test.create_stubs({cinder: ('volume_create',
- 'volume_snapshot_list',
- 'volume_type_list',
- 'tenant_absolute_limits',
- 'volume_list',),
- api.glance: ('image_list_detailed',)})
- def test_create_volume_encrypted(self):
- volume = self.volumes.first()
- volume_type = self.volume_types.first()
- usage_limit = {'maxTotalVolumeGigabytes': 250,
- 'gigabytesUsed': 20,
- 'maxTotalVolumes': 6}
- formData = {'name': u'An Encrypted Volume',
- 'description': u'This volume has metadata for encryption.',
- 'method': u'CreateForm',
- 'type': volume_type.name,
- 'size': 50,
- 'snapshot_source': '',
- 'encryption': u'LUKS'}
-
- # check normal operation with can_encrypt_volumes = true
- PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes']
- settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = True
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_snapshots.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
- cinder.volume_create(IsA(http.HttpRequest),
- formData['size'],
- formData['name'],
- formData['description'],
- formData['type'],
- metadata={'encryption': formData['encryption']},
- snapshot_id=None,
- image_id=None).AndReturn(volume)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:create')
- res = self.client.post(url, formData)
-
- redirect_url = reverse('horizon:project:volumes:index')
- self.assertRedirectsNoFollow(res, redirect_url)
-
- settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
-
- @test.create_stubs({cinder: ('volume_snapshot_list', 'volume_type_list',
- 'tenant_absolute_limits', 'volume_list',),
- api.glance: ('image_list_detailed',)})
- def test_create_volume_cannot_encrypt(self):
- # check that widget is hidden if can_encrypt_volumes = false
- PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes']
- settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = False
-
- usage_limit = {'maxTotalVolumeGigabytes': 250,
- 'gigabytesUsed': 20,
- 'maxTotalVolumes': 6}
-
- cinder.volume_type_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_types.list())
- cinder.tenant_absolute_limits(IsA(http.HttpRequest)).\
- AndReturn(usage_limit)
- cinder.volume_list(IsA(http.HttpRequest)).\
- AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)).\
- AndReturn(self.volume_snapshots.list())
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'is_public': True,
- 'status': 'active'}) \
- .AndReturn([self.images.list(), False])
- api.glance.image_list_detailed(IsA(http.HttpRequest),
- filters={'property-owner_id': self.tenant.id,
- 'status': 'active'}) \
- .AndReturn([[], False])
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:create')
- res = self.client.get(url)
-
- # Assert the encryption field is hidden.
- form = res.context['form']
- self.assertTrue(isinstance(form.fields['encryption'].widget,
- widgets.HiddenInput))
-
- settings.OPENSTACK_HYPERVISOR_FEATURES['can_encrypt_volumes'] = PREV
-
- @test.create_stubs({cinder: ('volume_list',
- 'volume_delete',),
- api.nova: ('server_list',)})
- def test_delete_volume(self):
- volume = self.volumes.first()
- formData = {'action':
- 'volumes__delete__%s' % volume.id}
-
- cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
- AndReturn(self.volumes.list())
- cinder.volume_delete(IsA(http.HttpRequest), volume.id)
- api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\
- AndReturn([self.servers.list(), False])
- cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
- AndReturn(self.volumes.list())
- api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\
- AndReturn([self.servers.list(), False])
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:index')
- res = self.client.post(url, formData, follow=True)
- self.assertIn("Scheduled deletion of Volume: Volume name",
- [m.message for m in res.context['messages']])
-
- @test.create_stubs({cinder: ('volume_list',
- 'volume_delete',),
- api.nova: ('server_list',)})
- def test_delete_volume_error_existing_snapshot(self):
- volume = self.volumes.first()
- formData = {'action':
- 'volumes__delete__%s' % volume.id}
- exc = self.exceptions.cinder.__class__(400,
- "error: dependent snapshots")
-
- cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
- AndReturn(self.volumes.list())
- cinder.volume_delete(IsA(http.HttpRequest), volume.id).\
- AndRaise(exc)
- api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\
- AndReturn([self.servers.list(), False])
- cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
- AndReturn(self.volumes.list())
- api.nova.server_list(IsA(http.HttpRequest), search_opts=None).\
- AndReturn([self.servers.list(), False])
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:index')
- res = self.client.post(url, formData, follow=True)
- self.assertMessageCount(res, error=1)
- self.assertEqual(list(res.context['messages'])[0].message,
- u'Unable to delete volume "%s". '
- u'One or more snapshots depend on it.' %
- volume.display_name)
-
- @test.create_stubs({cinder: ('volume_get',), api.nova: ('server_list',)})
- def test_edit_attachments(self):
- volume = self.volumes.first()
- servers = [s for s in self.servers.list()
- if s.tenant_id == self.request.user.tenant_id]
-
- cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
- api.nova.server_list(IsA(http.HttpRequest)).AndReturn([servers, False])
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:attach', args=[volume.id])
- res = self.client.get(url)
- # Asserting length of 2 accounts for the one instance option,
- # and the one 'Choose Instance' option.
- form = res.context['form']
- self.assertEqual(len(form.fields['instance']._choices),
- 2)
- self.assertEqual(res.status_code, 200)
- self.assertTrue(isinstance(form.fields['device'].widget,
- widgets.TextInput))
-
- @test.create_stubs({cinder: ('volume_get',), api.nova: ('server_list',)})
- def test_edit_attachments_cannot_set_mount_point(self):
- PREV = settings.OPENSTACK_HYPERVISOR_FEATURES['can_set_mount_point']
- settings.OPENSTACK_HYPERVISOR_FEATURES['can_set_mount_point'] = False
-
- volume = self.volumes.first()
- servers = [s for s in self.servers.list()
- if s.tenant_id == self.request.user.tenant_id]
-
- cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
- api.nova.server_list(IsA(http.HttpRequest)).AndReturn([servers, False])
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:attach', args=[volume.id])
- res = self.client.get(url)
- # Assert the device field is hidden.
- form = res.context['form']
- self.assertTrue(isinstance(form.fields['device'].widget,
- widgets.HiddenInput))
- settings.OPENSTACK_HYPERVISOR_FEATURES['can_set_mount_point'] = PREV
-
- @test.create_stubs({cinder: ('volume_get',),
- api.nova: ('server_get', 'server_list',)})
- def test_edit_attachments_attached_volume(self):
- servers = [s for s in self.servers.list()
- if s.tenant_id == self.request.user.tenant_id]
- server = servers[0]
- volume = self.volumes.list()[0]
-
- cinder.volume_get(IsA(http.HttpRequest), volume.id) \
- .AndReturn(volume)
- api.nova.server_list(IsA(http.HttpRequest)) \
- .AndReturn([servers, False])
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:attach',
- args=[volume.id])
- res = self.client.get(url)
-
- self.assertEqual(res.context['form'].fields['instance']._choices[0][1],
- "Select an instance")
- self.assertEqual(len(res.context['form'].fields['instance'].choices),
- 2)
- self.assertEqual(res.context['form'].fields['instance']._choices[1][0],
- server.id)
- self.assertEqual(res.status_code, 200)
-
- @test.create_stubs({cinder: ('volume_get',),
- api.nova: ('server_get',)})
- def test_detail_view(self):
- volume = self.volumes.first()
- server = self.servers.first()
-
- volume.attachments = [{"server_id": server.id}]
-
- cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
- api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:detail',
- args=[volume.id])
- res = self.client.get(url)
-
- self.assertContains(res, "<dd>Volume name</dd>", 1, 200)
- self.assertContains(res,
- "<dd>41023e92-8008-4c8b-8059-7f2293ff3775</dd>",
- 1,
- 200)
- self.assertContains(res, "<dd>Available</dd>", 1, 200)
- self.assertContains(res, "<dd>40 GB</dd>", 1, 200)
- self.assertContains(res,
- ("<a href=\"/project/instances/1/\">%s</a>"
- % server.name),
- 1,
- 200)
-
- self.assertNoMessages()
-
- @test.create_stubs({cinder: ('volume_get',)})
- def test_get_data(self):
- volume = self.volumes.first()
- volume.display_name = ''
-
- cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
-
- self.mox.ReplayAll()
-
- url = reverse('horizon:project:volumes:index') + \
- "?action=row_update&table=volumes&obj_id=" + volume.id
-
- res = self.client.get(url, {},
- HTTP_X_REQUESTED_WITH='XMLHttpRequest')
-
- self.assertEqual(res.status_code, 200)
- self.assertEqual(volume.display_name, volume.id)
diff --git a/openstack_dashboard/dashboards/project/volumes/urls.py b/openstack_dashboard/dashboards/project/volumes/urls.py
deleted file mode 100644
index 0d77d0a2..00000000
--- a/openstack_dashboard/dashboards/project/volumes/urls.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.project.volumes.views \
- import CreateSnapshotView
-from openstack_dashboard.dashboards.project.volumes.views import CreateView
-from openstack_dashboard.dashboards.project.volumes.views import DetailView
-from openstack_dashboard.dashboards.project.volumes.views \
- import EditAttachmentsView
-from openstack_dashboard.dashboards.project.volumes.views import IndexView
-
-
-urlpatterns = patterns('openstack_dashboard.dashboards.project.volumes.views',
- url(r'^$', IndexView.as_view(), name='index'),
- url(r'^create/$', CreateView.as_view(), name='create'),
- url(r'^(?P<volume_id>[^/]+)/attach/$',
- EditAttachmentsView.as_view(),
- name='attach'),
- url(r'^(?P<volume_id>[^/]+)/create_snapshot/$',
- CreateSnapshotView.as_view(),
- name='create_snapshot'),
- url(r'^(?P<volume_id>[^/]+)/$',
- DetailView.as_view(),
- name='detail'),
-)
diff --git a/openstack_dashboard/dashboards/project/volumes/views.py b/openstack_dashboard/dashboards/project/volumes/views.py
deleted file mode 100644
index cf3fbd95..00000000
--- a/openstack_dashboard/dashboards/project/volumes/views.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Views for managing volumes.
-"""
-
-from django.core.urlresolvers import reverse_lazy
-from django.utils.datastructures import SortedDict
-from django.utils.translation import ugettext_lazy as _
-
-from openstack_dashboard.dashboards.project.volumes.forms import AttachForm
-from openstack_dashboard.dashboards.project.volumes.forms import CreateForm
-from openstack_dashboard.dashboards.project.volumes.forms \
- import CreateSnapshotForm
-
-from horizon import exceptions
-from horizon import forms
-from horizon import tables
-from horizon import tabs
-
-import logging
-
-from openstack_dashboard import api
-from openstack_dashboard.api import cinder
-from openstack_dashboard.usage import quotas
-
-from openstack_dashboard.dashboards.project.volumes.tables \
- import AttachmentsTable
-from openstack_dashboard.dashboards.project.volumes.tables import VolumesTable
-from openstack_dashboard.dashboards.project.volumes.tabs \
- import VolumeDetailTabs
-
-
-LOG = logging.getLogger(__name__)
-
-
-class VolumeTableMixIn(object):
- def _get_volumes(self, search_opts=None):
- try:
- return cinder.volume_list(self.request, search_opts=search_opts)
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve volume list.'))
- return []
-
- def _get_instances(self, search_opts=None):
- try:
- instances, has_more = api.nova.server_list(self.request,
- search_opts=search_opts)
- return instances
- except:
- exceptions.handle(self.request,
- _("Unable to retrieve volume/instance "
- "attachment information"))
- return []
-
- def _set_id_if_nameless(self, volumes, instances):
- for volume in volumes:
- # It is possible to create a volume with no name through the
- # EC2 API, use the ID in those cases.
- if not volume.display_name:
- volume.display_name = volume.id
-
- def _set_attachments_string(self, volumes, instances):
- instances = SortedDict([(inst.id, inst) for inst in instances])
- for volume in volumes:
- for att in volume.attachments:
- server_id = att.get('server_id', None)
- att['instance'] = instances.get(server_id, None)
-
-
-class IndexView(tables.DataTableView, VolumeTableMixIn):
- table_class = VolumesTable
- template_name = 'project/volumes/index.html'
-
- def get_data(self):
- volumes = self._get_volumes()
- instances = self._get_instances()
- self._set_id_if_nameless(volumes, instances)
- self._set_attachments_string(volumes, instances)
- return volumes
-
-
-class DetailView(tabs.TabView):
- tab_group_class = VolumeDetailTabs
- template_name = 'project/volumes/detail.html'
-
-
-class CreateView(forms.ModalFormView):
- form_class = CreateForm
- template_name = 'project/volumes/create.html'
- success_url = reverse_lazy("horizon:project:volumes:index")
-
- def get_context_data(self, **kwargs):
- context = super(CreateView, self).get_context_data(**kwargs)
- try:
- context['usages'] = cinder.tenant_absolute_limits(self.request)
- volumes = cinder.volume_list(self.request)
- total_size = sum([getattr(volume, 'size', 0) for volume
- in volumes])
- context['usages']['gigabytesUsed'] = total_size
- context['usages']['volumesUsed'] = len(volumes)
-
- except:
- exceptions.handle(self.request)
- return context
-
-
-class CreateSnapshotView(forms.ModalFormView):
- form_class = CreateSnapshotForm
- template_name = 'project/volumes/create_snapshot.html'
- success_url = reverse_lazy("horizon:project:images_and_snapshots:index")
-
- def get_context_data(self, **kwargs):
- context = super(CreateSnapshotView, self).get_context_data(**kwargs)
- context['volume_id'] = self.kwargs['volume_id']
- try:
- context['usages'] = quotas.tenant_quota_usages(self.request)
- except:
- exceptions.handle(self.request)
- return context
-
- def get_initial(self):
- return {'volume_id': self.kwargs["volume_id"]}
-
-
-class EditAttachmentsView(tables.DataTableView, forms.ModalFormView):
- table_class = AttachmentsTable
- form_class = AttachForm
- template_name = 'project/volumes/attach.html'
- success_url = reverse_lazy("horizon:project:volumes:index")
-
- def get_object(self):
- if not hasattr(self, "_object"):
- volume_id = self.kwargs['volume_id']
- try:
- self._object = cinder.volume_get(self.request, volume_id)
- except:
- self._object = None
- exceptions.handle(self.request,
- _('Unable to retrieve volume information.'))
- return self._object
-
- def get_data(self):
- try:
- volumes = self.get_object()
- attachments = [att for att in volumes.attachments if att]
- except:
- attachments = []
- exceptions.handle(self.request,
- _('Unable to retrieve volume information.'))
- return attachments
-
- def get_initial(self):
- try:
- instances, has_more = api.nova.server_list(self.request)
- except:
- instances = []
- exceptions.handle(self.request,
- _("Unable to retrieve attachment information."))
- return {'volume': self.get_object(),
- 'instances': instances}
-
- def get_form(self):
- if not hasattr(self, "_form"):
- form_class = self.get_form_class()
- self._form = super(EditAttachmentsView, self).get_form(form_class)
- return self._form
-
- def get_context_data(self, **kwargs):
- context = super(EditAttachmentsView, self).get_context_data(**kwargs)
- context['form'] = self.get_form()
- volume = self.get_object()
- if volume and volume.status == 'available':
- context['show_attach'] = True
- else:
- context['show_attach'] = False
- context['volume'] = volume
- if self.request.is_ajax():
- context['hide'] = True
- return context
-
- def get(self, request, *args, **kwargs):
- # Table action handling
- handled = self.construct_tables()
- if handled:
- return handled
- return self.render_to_response(self.get_context_data(**kwargs))
-
- def post(self, request, *args, **kwargs):
- form = self.get_form()
- if form.is_valid():
- return self.form_valid(form)
- else:
- return self.get(request, *args, **kwargs)
diff --git a/openstack_dashboard/dashboards/settings/__init__.py b/openstack_dashboard/dashboards/settings/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/settings/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/settings/dashboard.py b/openstack_dashboard/dashboards/settings/dashboard.py
deleted file mode 100644
index 15116f20..00000000
--- a/openstack_dashboard/dashboards/settings/dashboard.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Openstack, LLC
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-
-class Settings(horizon.Dashboard):
- name = _("Settings")
- slug = "settings"
- panels = ('user', 'password', )
- default_panel = 'user'
- nav = False
-
-
-horizon.register(Settings)
diff --git a/openstack_dashboard/dashboards/settings/models.py b/openstack_dashboard/dashboards/settings/models.py
deleted file mode 100644
index 6313a32f..00000000
--- a/openstack_dashboard/dashboards/settings/models.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
-"""
diff --git a/openstack_dashboard/dashboards/settings/password/__init__.py b/openstack_dashboard/dashboards/settings/password/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/settings/password/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/settings/password/forms.py b/openstack_dashboard/dashboards/settings/password/forms.py
deleted file mode 100644
index 36963d49..00000000
--- a/openstack_dashboard/dashboards/settings/password/forms.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Centrin Data Systems Ltd.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.forms import ValidationError
-from django.utils.translation import ugettext_lazy as _
-from django.views.decorators.debug import sensitive_variables
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-from horizon.utils import validators
-
-from openstack_dashboard import api
-
-
-class PasswordForm(forms.SelfHandlingForm):
- current_password = forms.CharField(label=_("Current password"),
- widget=forms.PasswordInput(render_value=False))
- new_password = forms.RegexField(label=_("New password"),
- widget=forms.PasswordInput(render_value=False),
- regex=validators.password_validator(),
- error_messages={'invalid':
- validators.password_validator_msg()})
- confirm_password = forms.CharField(label=_("Confirm new password"),
- widget=forms.PasswordInput(render_value=False))
-
- def clean(self):
- '''Check to make sure password fields match.'''
- data = super(forms.Form, self).clean()
- if 'new_password' in data:
- if data['new_password'] != data.get('confirm_password', None):
- raise ValidationError(_('Passwords do not match.'))
- return data
-
- # We have to protect the entire "data" dict because it contains the
- # oldpassword and newpassword strings.
- @sensitive_variables('data')
- def handle(self, request, data):
- user_is_editable = api.keystone.keystone_can_edit_user()
-
- if user_is_editable:
- try:
- api.keystone.user_update_own_password(request,
- data['current_password'],
- data['new_password'])
- messages.success(request, _('Password changed.'))
- except:
- exceptions.handle(request,
- _('Unable to change password.'))
- return False
- else:
- messages.error(request, _('Changing password is not supported.'))
- return False
-
- return True
diff --git a/openstack_dashboard/dashboards/settings/password/panel.py b/openstack_dashboard/dashboards/settings/password/panel.py
deleted file mode 100644
index c9aba345..00000000
--- a/openstack_dashboard/dashboards/settings/password/panel.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Centrin Data Systems Ltd.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.dashboards.settings import dashboard
-
-
-class PasswordPanel(horizon.Panel):
- name = _("Change Password")
- slug = 'password'
-
-
-dashboard.Settings.register(PasswordPanel)
diff --git a/openstack_dashboard/dashboards/settings/password/templates/password/_change.html b/openstack_dashboard/dashboards/settings/password/templates/password/_change.html
deleted file mode 100644
index 7c258cde..00000000
--- a/openstack_dashboard/dashboards/settings/password/templates/password/_change.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}change_password_modal{% endblock %}
-{% block form_action %}{% url 'horizon:settings:password:index' %}{% endblock %}
-
-{% block modal_id %}change_password_modal{% endblock %}
-{% block modal-header %}{% trans "Change Password" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "From here you can change your password. We highly recommend you create a strong one. " %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <button type="submit" class="btn btn-primary">{% trans "Change" %}</button>
- {% if hide %}<a href="{% url 'horizon:settings:password:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>{% endif %}
-{% endblock %}
-
diff --git a/openstack_dashboard/dashboards/settings/password/templates/password/change.html b/openstack_dashboard/dashboards/settings/password/templates/password/change.html
deleted file mode 100644
index 5d0867f4..00000000
--- a/openstack_dashboard/dashboards/settings/password/templates/password/change.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "Change Password" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("Change Password") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "settings/password/_change.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/settings/password/tests.py b/openstack_dashboard/dashboards/settings/password/tests.py
deleted file mode 100644
index 409b1ef8..00000000
--- a/openstack_dashboard/dashboards/settings/password/tests.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Centrin Data Systems Ltd.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.core.urlresolvers import reverse
-from django import http
-
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-INDEX_URL = reverse('horizon:settings:password:index')
-
-
-class ChangePasswordTests(test.TestCase):
-
- @test.create_stubs({api.keystone: ('user_update_own_password', )})
- def test_change_password(self):
- api.keystone.user_update_own_password(IsA(http.HttpRequest),
- 'oldpwd',
- 'normalpwd',).AndReturn(None)
-
- self.mox.ReplayAll()
-
- formData = {'method': 'PasswordForm',
- 'current_password': 'oldpwd',
- 'new_password': 'normalpwd',
- 'confirm_password': 'normalpwd'}
-
- res = self.client.post(INDEX_URL, formData)
-
- self.assertNoFormErrors(res)
-
- def test_change_validation_passwords_not_matching(self):
-
- formData = {'method': 'PasswordForm',
- 'current_password': 'currpasswd',
- 'new_password': 'testpassword',
- 'confirm_password': 'doesnotmatch'}
-
- res = self.client.post(INDEX_URL, formData)
-
- self.assertFormError(res, "form", None, ['Passwords do not match.'])
diff --git a/openstack_dashboard/dashboards/settings/password/urls.py b/openstack_dashboard/dashboards/settings/password/urls.py
deleted file mode 100644
index cd3cf9b9..00000000
--- a/openstack_dashboard/dashboards/settings/password/urls.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Centrin Data Systems Ltd.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.settings.password.views import PasswordView
-
-
-urlpatterns = patterns('',
- url(r'^$', PasswordView.as_view(), name='index'))
diff --git a/openstack_dashboard/dashboards/settings/password/views.py b/openstack_dashboard/dashboards/settings/password/views.py
deleted file mode 100644
index 01114af0..00000000
--- a/openstack_dashboard/dashboards/settings/password/views.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Centrin Data Systems Ltd.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from horizon import forms
-
-from django.core.urlresolvers import reverse_lazy
-from openstack_dashboard.dashboards.settings.password.forms import PasswordForm
-
-
-class PasswordView(forms.ModalFormView):
- form_class = PasswordForm
- template_name = 'settings/password/change.html'
- success_url = reverse_lazy('logout')
diff --git a/openstack_dashboard/dashboards/settings/user/__init__.py b/openstack_dashboard/dashboards/settings/user/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/dashboards/settings/user/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/dashboards/settings/user/forms.py b/openstack_dashboard/dashboards/settings/user/forms.py
deleted file mode 100644
index 67cdb7d0..00000000
--- a/openstack_dashboard/dashboards/settings/user/forms.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from datetime import datetime
-import pytz
-
-from django.conf import settings
-from django import shortcuts
-from django.utils import translation
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import forms
-from horizon import messages
-
-
-class UserSettingsForm(forms.SelfHandlingForm):
- language = forms.ChoiceField(label=_("Language"))
- timezone = forms.ChoiceField(label=_("Timezone"))
- pagesize = forms.IntegerField(label=_("Items Per Page"),
- min_value=1,
- max_value=getattr(settings,
- 'API_RESULT_LIMIT',
- 1000),
- help_text=_("Number of items to show per "
- "page"))
-
- def __init__(self, *args, **kwargs):
- super(UserSettingsForm, self).__init__(*args, **kwargs)
-
- # Languages
- languages = [(k, "%s (%s)"
- % (translation.get_language_info(k)['name_local'], k))
- for k, v in settings.LANGUAGES]
- self.fields['language'].choices = languages
-
- # Timezones
- d = datetime(datetime.today().year, 1, 1)
- timezones = []
- for tz in pytz.common_timezones:
- try:
- utc_offset = pytz.timezone(tz).localize(d).strftime('%z')
- utc_offset = " (UTC %s:%s)" % (utc_offset[:3], utc_offset[3:])
- except:
- utc_offset = ""
-
- if tz != "UTC":
- tz_name = "%s%s" % (tz, utc_offset)
- else:
- tz_name = tz
- timezones.append((tz, tz_name))
-
- self.fields['timezone'].choices = timezones
-
- def handle(self, request, data):
- response = shortcuts.redirect(request.build_absolute_uri())
- # Language
- lang_code = data['language']
- if lang_code and translation.check_for_language(lang_code):
- if hasattr(request, 'session'):
- request.session['django_language'] = lang_code
- else:
- response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)
-
- # Timezone
- request.session['django_timezone'] = pytz.timezone(
- data['timezone']).zone
-
- request.session['horizon_pagesize'] = data['pagesize']
-
- messages.success(request, _("Settings saved."))
-
- return response
diff --git a/openstack_dashboard/dashboards/settings/user/panel.py b/openstack_dashboard/dashboards/settings/user/panel.py
deleted file mode 100644
index 635fe321..00000000
--- a/openstack_dashboard/dashboards/settings/user/panel.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.utils.translation import ugettext_lazy as _
-
-import horizon
-
-from openstack_dashboard.dashboards.settings import dashboard
-
-
-class UserPanel(horizon.Panel):
- name = _("User Settings")
- slug = 'user'
-
-
-dashboard.Settings.register(UserPanel)
diff --git a/openstack_dashboard/dashboards/settings/user/templates/user/_settings.html b/openstack_dashboard/dashboards/settings/user/templates/user/_settings.html
deleted file mode 100644
index f6605ff4..00000000
--- a/openstack_dashboard/dashboards/settings/user/templates/user/_settings.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "horizon/common/_modal_form.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block form_id %}user_settings_modal{% endblock %}
-{% block form_action %}{% url 'horizon:settings:user:index' %}{% endblock %}
-
-{% block modal_id %}user_settings_modal{% endblock %}
-{% block modal-header %}{% trans "User Settings" %}{% endblock %}
-
-{% block modal-body %}
-<div class="left">
- <fieldset>
- {% include "horizon/common/_form_fields.html" %}
- </fieldset>
-</div>
-<div class="right">
- <h3>{% trans "Description:" %}</h3>
- <p>{% trans "From here you can modify dashboard settings for your user." %}</p>
-</div>
-{% endblock %}
-
-{% block modal-footer %}
- <button type="submit" class="btn btn-primary">{% trans "Save" %}</button>
- {% if hide %}<a href="{% url 'horizon:settings:user:index' %}" class="btn secondary cancel close">{% trans "Cancel" %}</a>{% endif %}
-{% endblock %}
-
diff --git a/openstack_dashboard/dashboards/settings/user/templates/user/settings.html b/openstack_dashboard/dashboards/settings/user/templates/user/settings.html
deleted file mode 100644
index 0f68caee..00000000
--- a/openstack_dashboard/dashboards/settings/user/templates/user/settings.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-{% block title %}{% trans "User Settings" %}{% endblock %}
-
-{% block page_header %}
- {% include "horizon/common/_page_header.html" with title=_("User Settings") %}
-{% endblock page_header %}
-
-{% block main %}
- {% include "settings/user/_settings.html" %}
-{% endblock %}
diff --git a/openstack_dashboard/dashboards/settings/user/tests.py b/openstack_dashboard/dashboards/settings/user/tests.py
deleted file mode 100644
index c049a040..00000000
--- a/openstack_dashboard/dashboards/settings/user/tests.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.urlresolvers import reverse
-
-from openstack_dashboard.test import helpers as test
-
-
-INDEX_URL = reverse("horizon:settings:user:index")
-
-
-class UserSettingsTest(test.TestCase):
-
- def test_timezone_offset_is_displayed(self):
- res = self.client.get(INDEX_URL)
-
- self.assertContains(res, "Australia/Melbourne (UTC +11:00)")
- self.assertContains(res, "Europe/Moscow (UTC +04:00)")
- self.assertContains(res, "Atlantic/Stanley (UTC -03:00)")
- self.assertContains(res, "Pacific/Honolulu (UTC -10:00)")
diff --git a/openstack_dashboard/dashboards/settings/user/urls.py b/openstack_dashboard/dashboards/settings/user/urls.py
deleted file mode 100644
index 16cc7d94..00000000
--- a/openstack_dashboard/dashboards/settings/user/urls.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-
-from openstack_dashboard.dashboards.settings.user.views import UserSettingsView
-
-
-urlpatterns = patterns('',
- url(r'^$', UserSettingsView.as_view(), name='index'))
diff --git a/openstack_dashboard/dashboards/settings/user/views.py b/openstack_dashboard/dashboards/settings/user/views.py
deleted file mode 100644
index e57ba67e..00000000
--- a/openstack_dashboard/dashboards/settings/user/views.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf import settings
-from horizon import forms
-
-from openstack_dashboard.dashboards.settings.user.forms import UserSettingsForm
-
-
-class UserSettingsView(forms.ModalFormView):
- form_class = UserSettingsForm
- template_name = 'settings/user/settings.html'
-
- def get_initial(self):
- return {'language': self.request.LANGUAGE_CODE,
- 'timezone': self.request.session.get('django_timezone', 'UTC'),
- 'pagesize': self.request.session.get(
- 'horizon_pagesize',
- getattr(settings, 'API_RESULT_PAGE_SIZE', 20))}
-
- def form_valid(self, form):
- return form.handle(self.request, form.cleaned_data)
diff --git a/openstack_dashboard/exceptions.py b/openstack_dashboard/exceptions.py
deleted file mode 100644
index 958e075a..00000000
--- a/openstack_dashboard/exceptions.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.core.exceptions import ObjectDoesNotExist
-
-from cinderclient import exceptions as cinderclient
-from glanceclient.common import exceptions as glanceclient
-from heatclient import exc as heatclient
-from keystoneclient import exceptions as keystoneclient
-from neutronclient.common import exceptions as neutronclient
-from novaclient import exceptions as novaclient
-from swiftclient import client as swiftclient
-
-
-UNAUTHORIZED = (keystoneclient.Unauthorized,
- keystoneclient.Forbidden,
- cinderclient.Unauthorized,
- cinderclient.Forbidden,
- novaclient.Unauthorized,
- novaclient.Forbidden,
- glanceclient.Unauthorized,
- neutronclient.Unauthorized,
- neutronclient.Forbidden,
- heatclient.HTTPUnauthorized,
- heatclient.HTTPForbidden)
-
-NOT_FOUND = (keystoneclient.NotFound,
- cinderclient.NotFound,
- novaclient.NotFound,
- glanceclient.NotFound,
- neutronclient.NetworkNotFoundClient,
- neutronclient.PortNotFoundClient,
- heatclient.HTTPNotFound,
- # FIXME: this exception and the related import should be replaced
- # by the one thrown by the tuskar api client
- ObjectDoesNotExist)
-
-# NOTE(gabriel): This is very broad, and may need to be dialed in.
-RECOVERABLE = (keystoneclient.ClientException,
- # AuthorizationFailure is raised when Keystone is "unavailable".
- keystoneclient.AuthorizationFailure,
- cinderclient.ClientException,
- novaclient.ClientException,
- glanceclient.ClientException,
- # NOTE(amotoki): Neutron exceptions other than the first one
- # are recoverable in many cases (e.g., NetworkInUse is not
- # raised once VMs which use the network are terminated).
- neutronclient.NeutronClientException,
- neutronclient.NetworkInUseClient,
- neutronclient.PortInUseClient,
- neutronclient.AlreadyAttachedClient,
- neutronclient.StateInvalidClient,
- swiftclient.ClientException,
- heatclient.HTTPException)
diff --git a/openstack_dashboard/local/__init__.py b/openstack_dashboard/local/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/local/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/local/local_settings.py.example b/openstack_dashboard/local/local_settings.py.example
deleted file mode 100644
index fed29015..00000000
--- a/openstack_dashboard/local/local_settings.py.example
+++ /dev/null
@@ -1,367 +0,0 @@
-import os
-
-from django.utils.translation import ugettext_lazy as _
-
-from openstack_dashboard import exceptions
-
-DEBUG = True
-TEMPLATE_DEBUG = DEBUG
-
-# Required for Django 1.5.
-# If horizon is running in production (DEBUG is False), set this
-# with the list of host/domain names that the application can serve.
-# For more information see:
-# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
-#ALLOWED_HOSTS = ['horizon.example.com', ]
-
-# Set SSL proxy settings:
-# For Django 1.4+ pass this header from the proxy after terminating the SSL,
-# and don't forget to strip it from the client's request.
-# For more information see:
-# https://docs.djangoproject.com/en/1.4/ref/settings/#secure-proxy-ssl-header
-# SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
-
-# If Horizon is being served through SSL, then uncomment the following two
-# settings to better secure the cookies from security exploits
-#CSRF_COOKIE_SECURE = True
-#SESSION_COOKIE_SECURE = True
-
-# Overrides for OpenStack API versions. Use this setting to force the
-# OpenStack dashboard to use a specfic API version for a given service API.
-# NOTE: The version should be formatted as it appears in the URL for the
-# service API. For example, The identity service APIs have inconsistent
-# use of the decimal point, so valid options would be "2.0" or "3".
-# OPENSTACK_API_VERSIONS = {
-# "identity": 3
-# }
-
-# Set this to True if running on multi-domain model. When this is enabled, it
-# will require user to enter the Domain name in addition to username for login.
-# OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = False
-
-# Overrides the default domain used when running on single-domain model
-# with Keystone V3. All entities will be created in the default domain.
-# OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = 'Default'
-
-# Set Console type:
-# valid options would be "AUTO", "VNC" or "SPICE"
-# CONSOLE_TYPE = "AUTO"
-
-# Default OpenStack Dashboard configuration.
-HORIZON_CONFIG = {
- 'dashboards': ('project', 'admin', 'settings',),
- 'default_dashboard': 'project',
- 'user_home': 'openstack_dashboard.views.get_user_home',
- 'ajax_queue_limit': 10,
- 'auto_fade_alerts': {
- 'delay': 3000,
- 'fade_duration': 1500,
- 'types': ['alert-success', 'alert-info']
- },
- 'help_url': "http://docs.openstack.org",
- 'exceptions': {'recoverable': exceptions.RECOVERABLE,
- 'not_found': exceptions.NOT_FOUND,
- 'unauthorized': exceptions.UNAUTHORIZED},
-}
-
-# Specify a regular expression to validate user passwords.
-# HORIZON_CONFIG["password_validator"] = {
-# "regex": '.*',
-# "help_text": _("Your password does not meet the requirements.")
-# }
-
-# Disable simplified floating IP address management for deployments with
-# multiple floating IP pools or complex network requirements.
-# HORIZON_CONFIG["simple_ip_management"] = False
-
-# Turn off browser autocompletion for the login form if so desired.
-# HORIZON_CONFIG["password_autocomplete"] = "off"
-
-LOCAL_PATH = os.path.dirname(os.path.abspath(__file__))
-
-# Set custom secret key:
-# You can either set it to a specific value or you can let horizion generate a
-# default secret key that is unique on this machine, e.i. regardless of the
-# amount of Python WSGI workers (if used behind Apache+mod_wsgi): However, there
-# may be situations where you would want to set this explicitly, e.g. when
-# multiple dashboard instances are distributed on different machines (usually
-# behind a load-balancer). Either you have to make sure that a session gets all
-# requests routed to the same dashboard instance or you set the same SECRET_KEY
-# for all of them.
-from horizon.utils import secret_key
-SECRET_KEY = secret_key.generate_or_read_from_file(os.path.join(LOCAL_PATH, '.secret_key_store'))
-
-# We recommend you use memcached for development; otherwise after every reload
-# of the django development server, you will have to login again. To use
-# memcached set CACHES to something like
-# CACHES = {
-# 'default': {
-# 'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache',
-# 'LOCATION' : '127.0.0.1:11211',
-# }
-#}
-
-CACHES = {
- 'default': {
- 'BACKEND' : 'django.core.cache.backends.locmem.LocMemCache'
- }
-}
-
-# Send email to the console by default
-EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
-# Or send them to /dev/null
-#EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
-
-# Configure these for your outgoing email host
-# EMAIL_HOST = 'smtp.my-company.com'
-# EMAIL_PORT = 25
-# EMAIL_HOST_USER = 'djangomail'
-# EMAIL_HOST_PASSWORD = 'top-secret!'
-
-# For multiple regions uncomment this configuration, and add (endpoint, title).
-# AVAILABLE_REGIONS = [
-# ('http://cluster1.example.com:5000/v2.0', 'cluster1'),
-# ('http://cluster2.example.com:5000/v2.0', 'cluster2'),
-# ]
-
-OPENSTACK_HOST = "127.0.0.1"
-OPENSTACK_KEYSTONE_URL = "http://%s:5000/v2.0" % OPENSTACK_HOST
-OPENSTACK_KEYSTONE_DEFAULT_ROLE = "Member"
-
-# Disable SSL certificate checks (useful for self-signed certificates):
-# OPENSTACK_SSL_NO_VERIFY = True
-
-# The OPENSTACK_KEYSTONE_BACKEND settings can be used to identify the
-# capabilities of the auth backend for Keystone.
-# If Keystone has been configured to use LDAP as the auth backend then set
-# can_edit_user to False and name to 'ldap'.
-#
-# TODO(tres): Remove these once Keystone has an API to identify auth backend.
-OPENSTACK_KEYSTONE_BACKEND = {
- 'name': 'native',
- 'can_edit_user': True,
- 'can_edit_group': True,
- 'can_edit_project': True,
- 'can_edit_domain': True,
- 'can_edit_role': True
-}
-
-OPENSTACK_HYPERVISOR_FEATURES = {
- 'can_set_mount_point': True,
-
- # NOTE: as of Grizzly this is not yet supported in Nova so enabling this
- # setting will not do anything useful
- 'can_encrypt_volumes': False
-}
-
-# The OPENSTACK_NEUTRON_NETWORK settings can be used to enable optional
-# services provided by neutron. Currently only the load balancer service
-# is available.
-OPENSTACK_NEUTRON_NETWORK = {
- 'enable_security_group': True,
- 'enable_lb': False,
-}
-
-# OPENSTACK_ENDPOINT_TYPE specifies the endpoint type to use for the endpoints
-# in the Keystone service catalog. Use this setting when Horizon is running
-# external to the OpenStack environment. The default is 'publicURL'.
-#OPENSTACK_ENDPOINT_TYPE = "publicURL"
-
-# SECONDARY_ENDPOINT_TYPE specifies the fallback endpoint type to use in the
-# case that OPENSTACK_ENDPOINT_TYPE is not present in the endpoints
-# in the Keystone service catalog. Use this setting when Horizon is running
-# external to the OpenStack environment. The default is None. This
-# value should differ from OPENSTACK_ENDPOINT_TYPE if used.
-#SECONDARY_ENDPOINT_TYPE = "publicURL"
-
-# The number of objects (Swift containers/objects or images) to display
-# on a single page before providing a paging element (a "more" link)
-# to paginate results.
-API_RESULT_LIMIT = 1000
-API_RESULT_PAGE_SIZE = 20
-
-# The timezone of the server. This should correspond with the timezone
-# of your entire OpenStack installation, and hopefully be in UTC.
-TIME_ZONE = "UTC"
-
-LOGGING = {
- 'version': 1,
- # When set to True this will disable all logging except
- # for loggers specified in this configuration dictionary. Note that
- # if nothing is specified here and disable_existing_loggers is True,
- # django.db.backends will still log unless it is disabled explicitly.
- 'disable_existing_loggers': False,
- 'handlers': {
- 'null': {
- 'level': 'DEBUG',
- 'class': 'django.utils.log.NullHandler',
- },
- 'console': {
- # Set the level to "DEBUG" for verbose output logging.
- 'level': 'INFO',
- 'class': 'logging.StreamHandler',
- },
- },
- 'loggers': {
- # Logging from django.db.backends is VERY verbose, send to null
- # by default.
- 'django.db.backends': {
- 'handlers': ['null'],
- 'propagate': False,
- },
- 'requests': {
- 'handlers': ['null'],
- 'propagate': False,
- },
- 'horizon': {
- 'handlers': ['console'],
- 'propagate': False,
- },
- 'openstack_dashboard': {
- 'handlers': ['console'],
- 'propagate': False,
- },
- 'novaclient': {
- 'handlers': ['console'],
- 'propagate': False,
- },
- 'cinderclient': {
- 'handlers': ['console'],
- 'propagate': False,
- },
- 'keystoneclient': {
- 'handlers': ['console'],
- 'propagate': False,
- },
- 'glanceclient': {
- 'handlers': ['console'],
- 'propagate': False,
- },
- 'heatclient': {
- 'handlers': ['console'],
- 'propagate': False,
- },
- 'nose.plugins.manager': {
- 'handlers': ['console'],
- 'propagate': False,
- }
- }
-}
-
-SECURITY_GROUP_RULES = {
- 'all_tcp': {
- 'name': 'ALL TCP',
- 'ip_protocol': 'tcp',
- 'from_port': '1',
- 'to_port': '65535',
- },
- 'all_udp': {
- 'name': 'ALL UDP',
- 'ip_protocol': 'udp',
- 'from_port': '1',
- 'to_port': '65535',
- },
- 'all_icmp': {
- 'name': 'ALL ICMP',
- 'ip_protocol': 'icmp',
- 'from_port': '-1',
- 'to_port': '-1',
- },
- 'ssh': {
- 'name': 'SSH',
- 'ip_protocol': 'tcp',
- 'from_port': '22',
- 'to_port': '22',
- },
- 'smtp': {
- 'name': 'SMTP',
- 'ip_protocol': 'tcp',
- 'from_port': '25',
- 'to_port': '25',
- },
- 'dns': {
- 'name': 'DNS',
- 'ip_protocol': 'tcp',
- 'from_port': '53',
- 'to_port': '53',
- },
- 'http': {
- 'name': 'HTTP',
- 'ip_protocol': 'tcp',
- 'from_port': '80',
- 'to_port': '80',
- },
- 'pop3': {
- 'name': 'POP3',
- 'ip_protocol': 'tcp',
- 'from_port': '110',
- 'to_port': '110',
- },
- 'imap': {
- 'name': 'IMAP',
- 'ip_protocol': 'tcp',
- 'from_port': '143',
- 'to_port': '143',
- },
- 'ldap': {
- 'name': 'LDAP',
- 'ip_protocol': 'tcp',
- 'from_port': '389',
- 'to_port': '389',
- },
- 'https': {
- 'name': 'HTTPS',
- 'ip_protocol': 'tcp',
- 'from_port': '443',
- 'to_port': '443',
- },
- 'smtps': {
- 'name': 'SMTPS',
- 'ip_protocol': 'tcp',
- 'from_port': '465',
- 'to_port': '465',
- },
- 'imaps': {
- 'name': 'IMAPS',
- 'ip_protocol': 'tcp',
- 'from_port': '993',
- 'to_port': '993',
- },
- 'pop3s': {
- 'name': 'POP3S',
- 'ip_protocol': 'tcp',
- 'from_port': '995',
- 'to_port': '995',
- },
- 'ms_sql': {
- 'name': 'MS SQL',
- 'ip_protocol': 'tcp',
- 'from_port': '1443',
- 'to_port': '1443',
- },
- 'mysql': {
- 'name': 'MYSQL',
- 'ip_protocol': 'tcp',
- 'from_port': '3306',
- 'to_port': '3306',
- },
- 'rdp': {
- 'name': 'RDP',
- 'ip_protocol': 'tcp',
- 'from_port': '3389',
- 'to_port': '3389',
- },
-}
-
-# FIXME: this will eventually be unneeded, as it will be retrieved from Keystone
-#TUSKAR_ENDPOINT_URL = "http://127.0.0.1:6385"
-#NOVA_BAREMETAL_CREDS = {
-# 'user': 'admin',
-# 'password': 'admin_password_here',
-# 'tenant': 'admin',
-# 'auth_url': 'http://localhost:5001/v2.0/',
-# 'bypass_url': 'http://localhost:9774/v2/692567cd99f84f5d8f26ec23ff0ba460'
-#}
-#OVERCLOUD_AUTH_URL = 'http://127.0.0.1:5000/v2.0'
-#OVERCLOUD_USERNAME = 'admin'
-#OVERCLOUD_PASSWORD = 'password'
diff --git a/openstack_dashboard/locale/bg_BG/LC_MESSAGES/django.mo b/openstack_dashboard/locale/bg_BG/LC_MESSAGES/django.mo
deleted file mode 100644
index b2747f43..00000000
--- a/openstack_dashboard/locale/bg_BG/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/bg_BG/LC_MESSAGES/django.po b/openstack_dashboard/locale/bg_BG/LC_MESSAGES/django.po
deleted file mode 100644
index 430359fb..00000000
--- a/openstack_dashboard/locale/bg_BG/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4710 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Dimitar Dimitrov <dimitrov@linuxmail.org>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: bg_BG\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr ""
-
-#: settings.py:153
-msgid "Czech"
-msgstr ""
-
-#: settings.py:154
-msgid "English"
-msgstr "Английски"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Испански"
-
-#: settings.py:156
-msgid "French"
-msgstr "Френски"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Италиански"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Японски"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr ""
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr ""
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Полски"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Португалски"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr ""
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Опростен китайски"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Традиционен китайски"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr ""
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr ""
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr ""
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr ""
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr ""
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr ""
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr ""
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr ""
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr ""
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Проекти"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr ""
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr ""
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr ""
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr ""
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr ""
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Забранено"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Начало"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Страницата не беше намерена"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "Страницата, която търсите не съществува"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "Може да сте сбъркали адреса или страницата е преместена."
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr ""
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/ca/LC_MESSAGES/django.mo b/openstack_dashboard/locale/ca/LC_MESSAGES/django.mo
deleted file mode 100644
index a65499d2..00000000
--- a/openstack_dashboard/locale/ca/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/ca/LC_MESSAGES/django.po b/openstack_dashboard/locale/ca/LC_MESSAGES/django.po
deleted file mode 100644
index 1379c6fe..00000000
--- a/openstack_dashboard/locale/ca/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4710 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Sergi Almacellas <pokoli@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ca\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr ""
-
-#: settings.py:153
-msgid "Czech"
-msgstr ""
-
-#: settings.py:154
-msgid "English"
-msgstr "Anglès"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Castellà"
-
-#: settings.py:156
-msgid "French"
-msgstr "Francès"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Italià"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Japonès"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr ""
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr ""
-
-#: settings.py:161
-msgid "Polish"
-msgstr ""
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Portuguès"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "Portugès (Brasil)"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Chinès simplificat"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Chinès tradicional"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr "Instància desconeguda"
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr "Panell del Sistema"
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "Administració"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "Nom"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr "VCPUs"
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr "MB de RAM"
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr "GB del disc princpial"
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr "S'ha creat el sabor \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr "No s'ha pogut crear el sabor"
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr "S'ha actualitzat el sabor \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr "No s'ha pogut actualitzar el sabor"
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr "Sabors"
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr "Sabor"
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr "Crear Sabor"
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr "Editar Sabor"
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr "%sMB"
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr "Nom del Sabor"
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "RAM"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr "Disc Arrel"
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr "No s'ha pogut obtenir la llista de sabors"
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr "No s'ha pogut obtenir la inforamció del sabor. "
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr "Crea"
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr "Edita"
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "Descripció"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "Cancel·la"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr "Desa"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "Imatges"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr "Nom de la imatge"
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr "No s'ha pogut obtenir la llista d'imatges"
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr "Descripció:"
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr "Crea una imatge"
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr "Actualitza imatge"
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr "Nom de la quota"
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr "Límit"
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr "Quotes"
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr "Id"
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr "Servei"
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr "Amfitrió"
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr "Activat"
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr "Serveis"
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr "Quota per defecte"
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr "No s'ha pogut obtenir la informació de la quota"
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "Instàncies"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr "Instància"
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "Projecte"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr "Adreça IP"
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr "Mida"
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr "Estat"
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr "Tasca"
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr ""
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr "No s'ha pogut obtenir la llista d'instàncies"
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr ""
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr "Totes les instàncies"
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr "Compartit"
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr "Selecciona un projecte"
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr "La xarxa %s ha estat creada correctament."
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr "No s'ha pogut crear la xarxa %s"
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr "Identificador"
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr "La Xarxa %s s'ha actualitzat correctament."
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr "No s'ha pogut actualitzar la xarxa %s"
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "Xarxes"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr "Xarxa"
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr "No s'ha pogut eliminar la xarxa %s"
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr "Crear una xarxa"
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr "Edita una xarxa"
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "Nom de la xarxa"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr "Subxarxes associades"
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr "No es pot obtenir la llista de xarxes."
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr "No es pot obtenir la llista de subxarxes."
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr "No es pot obtenir la llista de ports"
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "Identificador de la Xarxa"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr "Identificador del dispositiu"
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr "S'ha creat correctament el port %s."
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr "No s'ha pogut crear el port %s."
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr "S'ha actualizat correctament el port %s."
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "Port"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "Ports"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr "Crear un port"
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr "Edita el port"
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr "Adreça IP fixa"
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr "Dispositiu vinculat"
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr ""
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr "Subxarxa"
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr "Subxarxes"
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr "Crear subxarxa"
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr "Editar subxarxa"
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr "Versió IP"
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr "Porta d'enllaç IP"
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr "Seleccioneu un nom per la vostra xarxa."
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr "Pots canviar les propietats editables de la xarxa des d'aquí."
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr "Guardar canvis"
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr "Actualitzar Xarxa"
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr "Actualitza el port"
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr "Detalls de la Xarxa"
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr "Actualitza Subxarxa"
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr "Monitoreig"
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Projectes"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr "Modificar usuaris"
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr "Visualitza l'ús"
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr "Crear Projecte"
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr "Editar Projecte"
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr "Identificador del projecte"
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr "Eliminar"
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr "Eliminat"
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr "Usuari"
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr "Usuaris"
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr "Rols"
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr "Usuaris del projecte"
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr "Afegir al projecte"
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr "Afegir nous usuaris"
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr "No s'ha pogut obtenir la informació del projecte"
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr "No s'ha pogut obtenir la llista de projectes"
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr "No s'han pogut obtenir els usuaris."
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr "No s'han pogut obtenir els valors de la quota predeterminada"
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr "No s'han pogut obtenir els detalls del projecte"
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr "Gigabytes"
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr "RAM (MB)"
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr "IP flotants"
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr "Quota"
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr "Informació del proejcte"
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr "Membres del projecte"
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr "Tots els usuaris"
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr "No s'han trobat usuaris"
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr "Afegir"
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr "Crear usuari"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr "Actualitza Quota"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr "Des d'aqui pots editar les quotes (límits màxims ) del projecte %(tenant.name)s."
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr "Actuailtza projecte"
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr "Des d'aqui pots editar un projecte"
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr "Afegir un nou usuari"
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr "Visió global de l'ús del projecte"
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr "Ús del projecte"
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr "Usuaris del projecte"
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr "Tipus"
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr "Les contrasenyes no coinicdeixen"
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr "Nom d'usuari"
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr "Correu electrònic"
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr "Contrasenya"
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr "Confirma la contrasenya"
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr "Projecte primari"
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr "Rol"
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr "L'usuari \"%s\" s'ha creat correctament."
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr "No s'ha pogut afegir l'usuari al projecte primari."
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr "No s'ha pogut crear l'usuari."
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr "nom"
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr "correu electrònic"
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr "projecte primàri"
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr "L'usuari %s no té cap rol definit"
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr "contrasenya"
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr "L'usuari s'ha actualitzat correctament"
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr "No s'han pogut actualitzar els %(attributes)s de l'usuari."
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr "Activa"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr "Desactiva"
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr "Descativat"
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr "No pots desactivat l'usuari amb el que estàs identificat actualment."
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr "ID d'usuari"
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr "No s'ha pogut actualitzar l'usuari."
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr "No s'han pogut obtenir els rols de l'usuari"
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr "Des d'aqui pots crear un nou usuari i asignar-lo a un projecte."
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr "Actualitza usuari"
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr "Des d'aqui pots editar els detalls de l'usuari, incloïent el seu projecte per defecte."
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr "Detalls del volum"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr "Detall del volum"
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr "Acces i Seguretat"
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr "No s'han pogut obtenir els grups de seguretat."
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr "Parells de claus"
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr "No s'ha pogut obtenir la llista de parells de clau."
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr "No s'han pogut obtenir les adreces IP flotants."
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr "No s'ha pogut obtenir els pools de IP flotants"
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr "Pool"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr "S'ha assigant la ip flotant %(ip)s."
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr "No s'ha pogut asignar la ip flotant"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr "Assigna una IP al projecte"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr "Allibera"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr "Alliberada"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr "IP flotant"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr "Associar IP flotant"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr "Desasociar IP flotant"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr "S'ha desasocioat correctament la IP flotant: %s"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr "No s'ha pofut desasociar la IP flotant."
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr "Pool de IP flotants"
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr "No hi ha pools d'IP flotants disponibles"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr "Seleccioneu l'adreça IP que voleu associar amb la instància seleccionada."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr "Selecciona una adreça IP"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr "No hi ha adreces IP disponibles"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr "Selecciona una instància"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr "No hi ha instàncies disponibles"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr "Gestiona les associacións d'IP flotants"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr "Associar"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr "L'adreça IP %s s'ha associat"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr "No s'ha pogut associar l'adreça IP %s."
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr "Nom del parell de claus"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr "Els parells de claus nomes poden contenir lletres,nombres, subratllats i guions."
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr "Clau pública"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr "S'ha importat la clau pública correctament: %s"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr "No s'ha pogut importar el parell de claus"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr "Parell de claus"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr "Importa parell de claus"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr "Crea parell de claus"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr "Emprempta"
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr "S'ha creat correctament el grup de seguretat: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr "No s'ha pogut crear el grup de seguretat"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr "Protocol IP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr "El protocol en el qual s'aplicarà la regla."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr "Port Origen"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr "Port destí"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr "Codi"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr "Origen"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr "El tipus ICMP és invàlid."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr "El codi ICMP és invàlid."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr "El nombre del port origen és invàlid."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr "El nombre del port destí és invàlid."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr "Editar regles"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr "Afegir regla"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr "Regla"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr "Regles"
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr "%s (actual)"
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr "Accès i Seguretat"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr "Quotes del projecte"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr "Descarrega parell de claus"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr "Swift"
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr "Contenidor"
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr "Nom del contenidor"
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr "El contenidor s'ha creat correctament."
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr "La carpeta s'ha creat correctament."
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr "No s'ha pogut crear el contenidor."
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr "Nom de l'objecte"
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr "Fitxer"
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr "L'objecte s'ha pujat correctament."
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr "No s'ha pogut pujar l'objecte."
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr "Contenidor destí."
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr "Objecte"
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr "Objectes"
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr "Copia"
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr "Descarrega"
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr "No s'ha pogut obtenir la llista de contenidors."
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr "Copiar un objecte"
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr "Puja un objecte al contenidor"
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr "Puja Objectes"
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr "Fomat"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr "AKI - Amazon Kernel Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr "AMI - Amazon Machine Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr "ARI - Amazon Ramdisk Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr "ISO - Imatge de disc Optic"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr "QCOW2 - Emulador QEMU"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr "Espái minim del disct (GB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr "Ram Mínima (MB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr "Pública"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr "Kernel ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr "Ramdisk ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr "Arquitectura"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr "La imatge s'ha actualtizat correctament."
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr "Imatge"
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr "No s'han pogut obtenir els detalls de la imatge"
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr "Informació"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr "Creada"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr "Actualitzada"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr "Tipus d'imatge"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr "Volum"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr "GB"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr "Crea un volum"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr "Nom del volum"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr "Pausa"
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr "Pausada"
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr "Suspen"
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr "Suspesa"
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr "Veure el registre"
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr "No disponible"
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr "Nom de la instància"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr "Registre"
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr "Recarrega"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr "Ves"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr "Veure el registre complert"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr "Adreces IP"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr "MB"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr "Nombre d'instàncies"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr "RAM total"
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr "Opcions del volum"
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr "Selecciona un volum"
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr "Nombre d'instàncies"
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr "Detalls"
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr "Selecciona la imatge"
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr "No hi ha imatges disponibles."
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr "Selecciona un parell de claus"
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr "No hi ha parells de claus disponibles"
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr "Adreça de la Xarxa"
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr "IP de la porta d'enllaç (opcional)"
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr "No s'han pogut obtenir els detalls de la subxarxa"
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr "Adreça IP:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr "Adreça MAC"
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr "Versió IP"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr "Mida (GB)"
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr "%sGB"
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr "Gigabytes totals"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr "Nombre de volums"
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr "Preferències"
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr "Preferències desades."
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr "Preferències del usuari"
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Prohibit"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Inici"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "No s'ha trobat la pàgina"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "La pàgina que esteu buscant no existeix"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr ""
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr "Ajuda"
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Identificat com"
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr "Sortir"
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr "La contrasenya ha de contenir entre 8 i 18 caràcters."
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr "Descarrega el resum en CSV"
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr "Nom del projecte"
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr "Resum de l'ús"
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr "Temps en funcionament"
diff --git a/openstack_dashboard/locale/cs/LC_MESSAGES/django.mo b/openstack_dashboard/locale/cs/LC_MESSAGES/django.mo
deleted file mode 100644
index e58f7729..00000000
--- a/openstack_dashboard/locale/cs/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/cs/LC_MESSAGES/django.po b/openstack_dashboard/locale/cs/LC_MESSAGES/django.po
deleted file mode 100644
index cc376e9f..00000000
--- a/openstack_dashboard/locale/cs/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4713 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# _AdamCz_ <a.skotnicky@tcpisek.cz>, 2013
-# jui <appukonrad@gmail.com>, 2012
-# pavlija7 <pavlk.jakub@gmail.com>, 2013
-# Jaroslav Henner <jaroslav.henner@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: cs\n"
-"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "bulharsky"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "česky"
-
-#: settings.py:154
-msgid "English"
-msgstr "anglicky"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "španělsky"
-
-#: settings.py:156
-msgid "French"
-msgstr "francouzsky"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "italsky"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "japonsky"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "korejsky"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "holandsky"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "polsky"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "portugalsky"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "Portugalsky"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "zjednodušená čínština"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "tradiční čínština"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr "Neznámá instance"
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr "%(type)s (%(backend)s backend)"
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr "Povolit %(from)s:%(to)s z %(group)s"
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr "Povolit %(from)s:%(to)s z %(cidr)s"
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr "Systémový panel"
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "Admin"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "Jméno"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr "VCPU"
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr "RAM MB"
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr "Root Disk GB"
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr "Efemérní Disk GB"
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr "Swap Disk MB"
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr "Nelze načíst seznam flavorů"
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr "Název \"%s\" je již využíván jiným flavor."
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr "Vytvořen flavor \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr "Nelze vytvořit flavor."
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr "Upraven flavor \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr "Nelze upravit flavor."
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr "Flavory"
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr "Flavor"
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr "Vytvořit flavor"
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr "Upravit flavor"
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr "Zobrazit extra specifikace"
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr "%s MB"
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr "Název flavoru"
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "RAM"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr "Root Disk"
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr "Efemérní Disk GB"
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr "Swap disk"
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr "Nelze získat seznam flavoru."
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr "Nelze získat flavor data."
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr "Klíč"
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr "Hodnota"
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr "Vytvořeny extra specifikace \"%s\"."
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr "Nemožné vytvořit flavor extra spec."
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr "Uloženy extra specifikace \"%s\"."
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr "Nemožné upravit extra spec."
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr "Extra specifikace"
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr "ExtraSpecs"
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr "Vytvořit"
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr "Upravit"
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr "Extra Specs"
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr "Nelze načíst seznam extra spec."
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr "Nelze načíst extra spec data flavoru"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "Popis"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr "Nastavte velikosti pro nový flavor."
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "Zrušit"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr "Odsud můžete změnit velikost současného flavoru."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr "Poznámka: toto neovlivní zdroje přidělené k jakékoliv existující instanci používající tento flavor."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr "Uložit"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr "Vytvořit Flavor Extra Spec"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr "Vytvořit nový \"extra spec\" klíčovou hodnotu pro flavor."
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr "Upravit flavor extra secifikace"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr "Aktualizovat \"extra spec\" key-value (klíčovou hodnotu) pro flavor."
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr "Flavor Extra Specs"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr "Zavřít"
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "Image"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr "Jméno Image"
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr "Nemožné získat image seznam."
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr "Vytvořit image"
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr "Popis:"
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr "Vyberte image pro nahrání do Image Service."
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr "V současnosti jsou podporovány image pouze skrze HTTP URL. Umístění image musí být dostupné pro Image Service. Komprimované image jsou podporovány (zip, tar a gz)."
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr "Vezměte prosím na vědomí:"
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr "Pole s umístěním image MUSÍ být validní a přímá URL do image binary. Adresy URL, které přesměrovávají nebo slouží pro zobrazení chybových stránek budou mít za následek nepoužitelnost imagů."
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr "Vytvořit image"
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr "Aktualizovat image"
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr "Zde můžete upravit různé vlastnosti image."
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr "Systémové informace"
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr "Název kvóty"
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr "Limit"
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr "Kvóty"
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr "Id"
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr "Služba"
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr "Host"
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr "Povolit"
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr "Služby"
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr "Základní kvóta"
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr "Nelze načíst informace o kvótě."
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "Instance"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr "Migrovat"
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr "Naplánována migrace (očekává se potvrzení) "
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr "Instance"
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "Projekt"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr "IP adresa"
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr "Velikost"
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr "Stav"
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr "Úloha"
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr "Stav"
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr "Nelze získat seznam instance."
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr "Nelze získat informace o nájemníkově instanci."
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr "Nelze získat informace o velikosti instance."
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr "Všechny instance."
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr "Admin status"
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr "Sdíleno"
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr "Externí síť"
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr "Vybrat projekt"
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr "Síť %s byla úspěšně vytvořena."
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr "Neúspěch při vytváření sítě %s"
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr "ID"
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr "Síť %s byla úspěšně aktualizována."
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr "Neúspěch při aktualizování síťě %s"
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "Sítě"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr "Síť"
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr "Neúspěch při vymazávání síťě %s"
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr "Vytvořit síť"
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr "Upravit síť"
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "Název sítě"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr "Subnety připojeny"
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr "Nelze získat seznam sítě."
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr "Nelze získat seznam subnetu."
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr "Nelze získat seznam portu."
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr "Nelze získat detaily pro síť \"%s\"."
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "ID sítě"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr "ID zařízení"
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr "Vlastník zařízení"
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr "Port %s byl úspěšně vytvořen."
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr "Neúspěch při vytváření portu pro síť %s"
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr "Port %s byl úspěšně aktualizován."
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr "Neúspěch při aktualizaci portu %s"
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "Port"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "Porty"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr "Neúspěch při vymazávání subnetu %s"
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr "Vytvořit port"
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr "Upravit port"
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr "Statické IP adresy"
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr "Zařízení připojeno"
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr "Přehled"
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr "Nelze získat detaily portu."
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr "Nelez načíst síť."
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr "Subnet"
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr "Subnety"
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr "Vytvořit subnet"
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr "Upravit subnet"
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr "CIDR"
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr "IP verze"
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr "IP brány"
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr "Neúspěch při načítání sítě %s pro subnet"
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr "Vyberte název pro vaší síť."
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr "Zde můžete upravit vlastnosti vaší sítě."
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr "Uložit změny"
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr "Aktualizovat síť"
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr "Můžete vytvořit port pro síť. Pokud specifikujete ID zařízení, které má být připojeno, zařízení se připojí na port který vytvoříte."
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr "Zde můžete upravit vlastnosti vašeho portu."
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr "Upravit port"
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr "Detail síťě"
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr "Upravit subnet"
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr "Přehled využití"
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr "Monitoring"
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Projekty"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr "Upravit uživatele"
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr "Náhled využití"
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr "Vytvořit projekt"
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr "Upravit projekt"
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr "Projekt ID"
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr "Vymazat"
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr "Vymazáno"
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr "Uživatel"
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr "Uživatelé"
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr "Nelze načíst informaci o roli."
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr "Role"
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr "Uživatelé pro projekt"
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr "Přidat do projektu"
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr "Přidat nové uživatele"
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr "Nelze načíst informace o projektu."
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr "Nelze načíst seznam projektu."
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr "Nelze načíst uživatele."
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr "Nelze načíst hodnoty základní kvóty."
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr "Nelze načíst detaily projektu."
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr "Injektovaný soubor obsahuje Byty(Bytes)"
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr "Metadata položky"
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr "Injektované soubory"
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr "Svazky"
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr "Gigabytes"
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr "RAM (MB)"
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr "Plovoucí IP adresy"
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr "Bezpečnostní skupiny"
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr "Pravidla bezpečnostní skupiny"
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr "Kvóta"
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr "Zde můžete nastavit kvóty (max. limity) pro projekty."
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr "Projekt info"
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr "Zde můžete vytvořit nový projekt pro organizaci uživatelů."
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr "Nelze načíst seznam uživatelů. Prosím zkuste to později."
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr "Nelze najít standardní roli \"%s\" v Keystone"
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr "Členové projektu"
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr "Všichni uživatelé"
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr "Nenalezeni žádní uživatelé."
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr "Žádní uživatelé."
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr "Nelze načíst seznam uživatelů."
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr "Vytvořen nový projekt \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr "Nelze vytvořit projekt \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr "Neúspěch při přidávání uživatelů a nastavování kvót pro projekt %s."
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr "Nelze nastavit kvótu pro projekt."
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr "Zde můžete upravit detaily projektu. "
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr "Upraven projekt \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr "Nelze upravit projekt \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr "Nemůžete odstranit \"admin\" roli z projektu do kterého jste právě přihlášen. Prosím přihlašte se do jiného projektu s admin právy nebo odstraňte roli manuálně skrze CLI."
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr "Neúspěch při upravování uživatelů a kvót pro projekt %s."
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr "Upraveni uživatelé a informace o projektu, ale nebylo možné upravit kvótu projektu."
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr "Přidat uživatele do projektu."
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr "Vyberte roli uživatele pro projekt."
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr "Přidat"
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr "Vytvořit uživatele pro projekt '%(tenant_name)s'."
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr "Zde můžete vytvořit nového uživatele a přidat ho do tohoto projektu. "
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr "Vytvořit uživatele"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr "Upravit kvótu"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr "Zde můžete upravit kvóty (max. limity) pro projekt %(tenant.name)s."
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr "Aktualizovat projekt"
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr "Zde můžete upravit projekt."
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr "Zde můžete přidat nebo odebrat uživatele tohoto projektu z listu dostupných uživatelů."
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr "Přidat nového uživatele"
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr "Upravit kvóty projektu"
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr "Přehled využití projektu"
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr "Využití projektu"
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr "Uživatelé projektu"
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr "Uživatelé pro projekt"
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr "Název routeru"
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr "Nemožné získat nájemníky."
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr "Nepodařilo se vytvořit router \"%s\"."
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr "Vytvořit router"
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr "Routery"
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr "Nelze načíst seznam routeru."
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr "Typ"
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr "Interfaces"
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr "Vytvořit router"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr "Přehled routeru"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr "Informace externí brány"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr "Připojené externí sítě"
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr "Vytvořit router"
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr "Detaily routeru"
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr "Detail routeru"
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr "Přidat interface"
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr "Můžete připojit specifikovaný subnet do routeru."
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr "Přidat interface"
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr "Nastavit bránu"
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr "Můžete připojit specifikovanou externí síť do routeru. Externí síť je považována za výchozí trasu routeru a router funguje jako brána pro vnější připojení."
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr "Hesla se neschodují."
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr "Uživatelské jméno"
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr "Email"
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr "Heslo"
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr "Potvrdit heslo"
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr "Primární projekt"
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr "Role"
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr "Uživatel \"%s\" byl úspěšně vytvořen."
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr "Nelze přidat uživatele do primárního projektu."
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr "Nelze vytvořit uživatele."
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr "jméno"
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr "email"
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr "primární projekt"
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr "Uživatel %s nemá definovanou roli pro"
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr "heslo"
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr "Uživatel byl úspěšně upraven."
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr "Nelze upravit %(attributes)s pro uživatele."
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr "Povolit"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr "Zakázat"
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr "Zakázáno"
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr "Nemůžete zakázat uživatele pod kterým jste zrovna přihlášen."
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr "Uživatelovo ID"
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr "Nelze upravit uživatele."
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr "Nelze načíst uživatelovi role."
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr "Zde můžete vytvořit nového uživatele a přidělit ho do projektu."
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr "Aktualizovat uživatele"
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr "Zde můžete upravit detaily uživatelů, včetně jejich základních projektů. "
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr "Úspěšně vytvořen svazek typu: %s"
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr "Nelze vytvořit typ svazku."
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr "Vytvořit typ svazku"
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr "Typ svazku"
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr "Typy svazků"
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr "Nemožné načíst informace nájemcova svazku."
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr "Nelze načíst typy svazků"
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr "\nTyp volume definuje jeho vlastnosti.\nObvykle mapuje schopnosti úložiště skrze ovladač, který se používá pro tento volume.\nPříklady: \"Performance\", \"SSD\", \"Záloha\", atd..."
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr "Vytvořit typ svazku"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr "Detaily svazku"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr "Detail svazku"
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr "Spravovat Compute"
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr "Objektové úložiště"
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr "Přístup a bezpečnost"
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr "Nelze načíst bezpečnostní skupiny."
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr "Keypairs"
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr "Nelze načíst keypair seznam."
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr "Nelze načíst plovoucí IP adresy."
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr "Nelze načíst pool plovoucích IP."
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr "Přístup k API"
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr "Stáhnout EC2 pověření"
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr "Stáhnout OpenStack RC soubor"
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr "Endpoint služby"
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr "API Endpointů"
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr "Nelze načíst EC2 pověření."
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr "Chyba při zapisování zip souboru: %(exc)s"
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr "Chyba při stahování RC souboru: %s"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr "Pool"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr "Alokované plovoucí IP %(ip)s."
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr "Nelze alokovat plovoucí IP."
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr "Alokovat IP do projektu"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr "Uvolnit"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr "Uvolněno"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr "Plovoucí IP"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr "Připojit plovoucí IP"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr "Odpojit plovoucí IP"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr "Úspěšně odpojena plovoucí IP: %s"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr "Nelze odpojit plovoucí IP."
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr "Pool plovoucích IP"
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr "Žádný pool plovoucích IP není dostupný."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr "Vyberte IP adresu, kterou si přejete připojit k vybrané instanci."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr "Port, který má být asociován"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr "Instance, která má být spojena"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr "Vyberte IP adresu."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr "Žádné dostupné IP adresy"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr "Zvolte port"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr "Vyberte instanci"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr "Žádný port není dostupný"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr "Žádné dostupné instance"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr "Spravovat připojené plovoucí IP"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr "Připojit"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr "Připojené IP adresy %s."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr "Nelze připojit IP adresu %s."
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr "Název keypair"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr "Keypair názvy mohou obsahovat pouze písmena, čísla, potržítka a pomlčky."
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr "Veřejný klíč"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr "Úspěšně importované veřejné klíče: %s"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr "Nelze importovat keypair."
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr "Keypair"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr "Importovat keypair"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr "Vytvořit keypair"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr "Otisk"
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr "Nelze vytvořit keypair: %(exc)s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr "Toto pole je povinné."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr "Řetězec může obsahovat pouze ASCII znaky."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr "Úspěšně vytvořena bezpečnostní skupina: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr "Nelze vytvořit bezpečnostní skupinu."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr "IP protokol"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr "TCP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr "UDP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr "ICMP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr "Protokol na který bude aplikováno pravidlo."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr "Otevřít"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr "Rozsah portů"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr "Zadejte číslo mezi 1 a 65535."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr "Z portu"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr "Do portu"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr "Zadej hodnotu pro typ ICMP v rozsahu (-1: 255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr "Kód"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr "zadej hodnotu pro kód ICMP v rozsahu (-1: 255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr "Zdroj"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr "Bezpečnostní skupina"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr "Pro povolení IP rozsahů vyberte \"CIDR\". Pro povolení všech členů jiné bezpečnostní skupiny vyberte \"Bezpečnostní skupiny\"."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr "Classless Inter-Domain Routing (např. 192.168.0.0/24)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr "Žádné bezpečnostní skupiny nejsou dostupné"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr "ICMP typ je neplatný."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr "ICMP kód je neplatný."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr "ICMP typ není v rozsahu (-1, 255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr "ICMP kód není v rozsahu (-1, 255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr "Zvolený port je špatný."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr "Číslo portu \"Z\" je neplatné."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr "Číslo portu \"Do\" je neplatné."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr "Číslo portu \"Do\"musí být vyšší nebo stejné jako číslo portu \"Z\"."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr "Úspěšně přidáno pravidlo: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr "Nelze přidat pravidlo do bezpečnostní skupiny."
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr "Vytvořit bezpečnostní skupinu"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr "Upravit pravidla"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr "Přidat pravidlo"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr "Pravidlo"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr "Pravidla"
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr "Nelze načíst bezpečnostní skupinu."
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr "%s (aktuálně)"
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr "Přístup a bezpečnost"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr "Alokovat plovoucí IP"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr "Alokovat plovoucí IP z přiděleného poolu plovoucích IP."
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr "Kvóty projektu"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr "Alokovat IP"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr "Keypairs jsou ssh klíče, které jsou injektovány do image při jeho startu. Pro vytvoření nového keypair zaregistrujte veřejný klíč a stáhněte privátní klíč (.pem soubor)."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr "Chraňte a používejte klíč jako kterýkoliv jiný normální ssh privátní klíč."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr "Stáhnout keypair"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr "Keypair &quot;%(keypair_name)s&quot; by měl být stažen automaticky. Pokud ne, použijte odkaz dole."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr "Stáhnout keypair &quot;%(keypair_name)s&quot;"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr "Pravidla definují povolený provoz do instance přiřazené do bezpečnostní skupiny. Pravidlo bezpečnostní skupiny se skládá ze tří základních částí: "
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr "Protokol"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr "Musíte vybrat požadovaný IP protokol, na který bude toto pravidlo aplikováno. Na výběr je TCP, UDP nebo ICMP."
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr "Otevřít port/port rozsah"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr "Pro TCP a UDP pravidla se můžete rozhodnout otevřít jeden port nebo rozsah portů. Volba \"Rozsah portů\" vám poskytne prostor jak pro počáteční tak pro koncový port. Pro ICMP pravidelo místo toho zadat ICMP typ a kód do uvedených polí."
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr "Musíte specifikovat zdroj provozu který má být povolen skrze toto pravidlo. Můžete tak udělat formou adresního bloku (CIDR) nebo skrze bezpečnostní skupinu (Bezpečnostní skupiny). Vybráním bezpečnostní skupiny jako zdroje povolíte všem ostatním instancím v této bezpečnostní skupině přístup na všechny instance v této skupině."
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr "Zde můžete vytvořit novou bezpečnostní skupinu"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr "Upravit pravidla bezpečnostní skupiny"
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr "Swift"
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr "Kontejner"
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr "Lomítko není povolený znak."
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr "Název kontejneru"
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr "Kontejner byl úspěšně vytvořen."
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr "Složka byla úspěšně vytvořena."
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr "Nelze vytvořit kontejner."
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr "Název objektu"
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr "Lomítka jsou povoleny a jsou považovány za pseudo-složky u objektového úložiště."
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr "Soubor"
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr "Objekt byl úspěšně nahrán."
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr "Nelze nahrát objekt."
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr "Cílový kontejner"
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr "Cílový název objektu"
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr "Zkopírováno \"%(orig)s\" do \"%(dest)s\" jako \"%(new)s\"."
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr "Nelze zkopírovat objekt."
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr "Kontejnery"
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr "Vytvořit kontejner"
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr "Zobrazit kontejner"
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr "Nahrát objekt"
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr "Objekt"
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr "Objekty"
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr "Kopírovat"
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr "Stáhnout"
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr "Nelze načíst seznam kontejneru."
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr "Nelze načíst seznam objektu."
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr "Nelze načíst objekt."
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr "Nelze vypsat kontejnery."
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr "Kopírovat objekt"
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr "Vytvořte novou kopii existujícího objektu pro uložení v tomto nebo v jiném kontejneru. Můžete také zadat cestu, v které nová kopie musí být uvnitř vybraného kontejneru."
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr "Kontejner je oddělení úložiště pro vaše data a poskytuje cestu jak organizovat vaše data. Představte si kontejner jako složku ve Windows &reg; nebo jako adresář v UNIX &reg;. Hlavní rozdíl mezi kontejnerem a ostatními souborovými systémy je, že kontejner nemůže být vnořován. Nicméně můžete vytvořit neomezené množství kontejnerů ve vašem účtu. Data musí být ukládána do kontejnerů, takže musíte mít definován alespoň jeden kontejner ve vašem účtu, kam budou nahrávaná data. "
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr "Nahrát objekt do kontejneru"
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr "Objekt je základní jednotka úložiště, která reprezentuje soubor uložený do úložiště OpenStack Object Storagy systému. Když nahráváš data do OpenStack Object Storage, data jsou uložena jak jsou (bez komprese nebo šifrování) a obsahují umístění (container), jméno objektu a metadata s key/value páry."
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr "Pseudo složka"
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr "Uvnitř kontejneru můžete seskupit objekty do pseudo-složek, které se chovají podobně jako složky ve vašem operačním systému, s výjimkou, že jsou virtuální sbírky definované společným prefixem názvu daného objektu. Lomítko (/) se používá jako oddělovač pseudo-složek v Úložišti objektů."
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr "Nahrát objekty"
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr "Images & snapshots"
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr "Nelze získat images."
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr "Nelze získat snapshoty."
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr "Nelze načíst snapshoty svazků."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr "Umístění image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr "Externí (HTTP) URL pro nahrání image."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr "Image soubor"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr "Formátovat"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr "AKI - Amazon Kernel Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr "AMI - Amazon Machine Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr "ARI - Amazon Ramdisk Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr "ISO - Optical Disk Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr "QCOW2 - QEMU Emulator"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr "Minimální disk (GB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr "Minimální velikost disku je požadována pro bootování z image. Pokud je nespecifikována, tak základní hodnota bude 0."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr "Minimální Ram (MB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr "Veřejné"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr "Umístění image nebo externího image musí být specifikováno."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr "Nemůžete specifikovat umístění jak externí image tak image."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr "Váš image %s byl zařazen pro vytvoření."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr "Nelze vytvořit nový image."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr "Kernel ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr "Ramdisk ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr "Architektura"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr "Nelze aktualizovat image \"%s\"."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr "Image byl úspěšně aktualizován."
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr "Spustit"
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr "Image"
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr "Nelze načíst detaily image. "
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr "Nelze načíst image."
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr "ID instance"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr "Název snapshotu"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr "Snapshot \"%(name)s vytvořen z instance \"%(inst)s\""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr "Nelze vytvořit snapshot."
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr "Snapshot"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr "Snapshoty"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr "Snapshoty instance"
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr "Nelze načíst instanci."
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr "Image a snapshoty"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr "Přehled image"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr "Info"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr "Kontrolní součet"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr "Vytvořeno"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr "Aktualizováno"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr "Specifikace"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr "Formát kontejneru"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr "Formát disku"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr "Uživatelské vlastnosti"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr "Euca2ools stav"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr "Typ image"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr "Image detail"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr "Vytvořit snapshot"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr "Snapshoty zachovají stav disku z běžící instance."
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr "Svazek"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr "GB"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr "Vytvořit snapshot"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr "Detaily o snapshotu svazku"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr "Detail o snapshotu svazku"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr "Snapshot svazku"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr "Snapshoty svazku"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr "Plánované odstranění na"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr "Vytvořit svazek"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr "Název svazku"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr "Nelze načíst detaily snapshotu."
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr "Ukončit"
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr "Naplánovat ukončení na"
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr "Tvrdý restart"
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr "Tvrdě restartováno"
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr "Měkký restart"
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr "Měkce restartováno"
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr "Pause"
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr "Pokračovat"
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr "Pozastavený"
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr "Obnoveno"
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr "Uspat"
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr "Uspaný"
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr "Spustit instanci"
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr "(kvóta byla překročena)"
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr "Upravit instanci"
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr "Upravit bezpečnostní skupiny"
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr "Konzole"
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr "Zobrazit log"
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr "Potvrdit Resize/Migraci"
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr "Vrátit Resize/Migraci"
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr "Úspěšně spojeno s plovoucí IP:%s"
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr "Nemožné spojit s plovoucí IP."
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr "Úspěšně odpojeno od plovoucí IP: %s"
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr "Žádné plovoucí IP pro odpojení."
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr "Není dostupné"
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr "Název instance"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr "Log"
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr "Nelze získat log z instance \"%s\"."
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr "Nelze načíst instance."
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr "Nelze spustit VNC konzoli z instance \"%s\"."
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr "Nemožné zobrazit SPICE konzoly pro instanci \"%s\"."
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr "Nelze načíst detail instance."
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr "Nelze načíst detail z instance \"%s\"."
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr "Konzole instance"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr "Jestliže konzole neodpovídá na příkazy: klikněte na šedý stavový panel dole."
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr "Klikněte zde pro zobrazení pouze konzole."
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr "Konzole je dočasně nedostupná. Prosím zkuste to později."
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr "Znovu načíst"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr "Konzole log instance"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr "Délka logu"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr "OK"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr "Zobrazit celý log"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr "Přehled instance"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr "VCPU"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr "Disk"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr "IP adresy"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr "Nenalezeno žádné pravidlo."
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr "Meta"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr "Název klíče"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr "Připojené svazky"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr "Připojeno do"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr "na"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr "Nepřipojeny žádné svazky."
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr "Můžete upravit vaší instanci po jejím spuštění, použitím možností dostupných zde."
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr "Pole \"Vlastní skript\" je podobné jako \"Uživatelská data\" v ostatních systémech."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr "Specifikujte detaily pro spuštění instance."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr "Grafy zobrazují využití zdrojů tímto projektem ve vztahu k projektovým kvótám."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr "Flavor detail"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr "Disk celkem"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr "MB"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr "Počet instancí"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr "Počet VCPU"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr "Celkem RAM"
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr "Vyberte síť z dostupných sítí do vybraných sítí zmáčknutím tlačítka nebo použijte \"drag and drop\", stejně můžete změnit pořadí NIC."
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr "Instance může být spuštěna s různými druhy úložiště. Vyberte si z následujících možností."
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr "Vybrané sítě"
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr "Dostupné sítě"
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr "Instance detail"
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr "Projekt a uživatel"
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr "Nebootovat ze svazku."
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr "Bootovat ze svazku."
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr "Bootovat ze snapshotu svazku (vytvoří nový svazek)."
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr "Možnosti svazku"
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr "Název zařízení"
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr "Přípojný bod pro svazek (např. 'vda' připojeno do '/dev/vda')."
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr "Odstranit ukončit"
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr "Odstranit svazek z instance a ukončit"
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr "Prosím zvolte svazek nebo vyberte %s."
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr "Vybrat svazek"
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr "Nelze načíst seznam svazků."
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr "Vyberte snapshot svazku"
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr "Nelze načíst seznam snapshotů svazku."
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr "Zdroj instance"
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr "Snapshot instance"
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr "Velikost image pro start."
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr "Počet instancí"
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr "Počet instancí pro spuštění."
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr "Detaily"
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr "Nejsou zde žádné zdrojové image. Musíte nejdříve vytvořit image než se pokusíte spustit instanci."
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr "Prosím, vyberte jednu z možností pro vlastníka zdroje."
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr "Spouštění několika instancí je podporováno pouze pro image a snapshoty instancí."
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr "Nelze načíst veřejné image."
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr "Nelze načíst image pro současný projekt."
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr "Vyberte image"
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr "Žádné dostupné image."
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr "Vyberte snapshot instance"
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr "Žádné dostupné snapshoty."
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr "Nelze načíst flavors instance."
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr "Nelze načíst informace o kvótě."
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr "Keypair, který se má použít pro ověření."
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr "Spustit instanci v těchto bezpečnostních skupinách."
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr "Kontrolujte přístup do vaší instance skrze keypairs, bezpečnostní skupiny a další mechanismy."
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr "Nelze načíst keypair."
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr "Vybrat keypair"
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr "Žádné keypairs k dispozici."
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr "Nelze načíst seznam bezpečnostních skupin."
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr "Vlastní skript"
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr "Skript nebo sada příkazů bude provedena po sestavení instance (max. 16kb)."
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr "Po vytvoření"
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr "Alespoň jedna síť musí být vybrána."
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr "Spustí instanci s těmito sítěmi"
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr "Sítě"
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr "Vyberte síť pro vaší instanci."
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr "Nelze načíst sítě."
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr "Spuštěno %(count)s pojmenovaných \"%(name)s\"."
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr "Nelze spustit %(count)s pojmenovaných \"%(name)s\"."
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr "%s instance"
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr "instance"
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr "Nelze načíst seznam bezpečnostních skupin. Prosím zkuste to později."
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr "Nelze získat seznam současné bezpečnostní skupiny pro instanci %s."
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr "Nepodařilo se upravit %d instance bezpečnostní skupiny."
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr "Zde můžete přidat nebo odebrat bezpečnostní skupiny do tohoto projektu ze seznamu dostupných bezpečnostních skupin."
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr "Všechny bezpečnostní skupiny"
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr "Bezpečnostní skupiny instance"
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr "Nenalezeny žádné bezpečnostní skupiny."
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr "Žádné bezpečnostní skupiny nejsou povoleny."
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr "Zde můžete upravit detaily instance."
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr "Upravena instance \"%s\"."
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr "Nelze upravit instanci \"%s\"."
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr "Load Balancery"
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr "Přidat pool"
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr "Přidat VIP"
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr "Přidat člena"
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr "Přidat monitor"
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr "Vymazat"
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr "VIP"
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr "VIP"
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr "Pooly"
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr "Monitor"
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr "Monitory"
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr "Člen"
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr "Členové"
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr "VIP"
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr "Port protokolu"
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr "Typ monitoru"
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr "Nelze načíst seznam poolu."
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr "Nelze načíst seznam členů."
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr "Nelze načíst seznam monitoru."
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr "Detaily poolu"
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr "Nelze načíst detaily poolu."
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr "Detaily VIP"
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr "Nelze načíst VIP detaily."
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr "Detaily člena"
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr "Nelze načíst detaily člena."
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr "Detaily monitoru"
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr "Nelze načíst detaily monitoru."
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr "Nelze vymazat monitor."
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr "Musíte vymazat VIP jako první."
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr "Nelze vymazat člena."
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr "Nelze najít VIP pro vymazání."
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr "Nelze vymazat VIP."
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr "Nelze načíst pool subnet."
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr "Metody load balancing"
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr "Vybrat subnet"
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr "Nelze načíst seznam sítí."
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr "Vybrat protokol"
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr "Detaily poolu"
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr "Vytvořit pool pro současného nájemníka.\n\nPřidělte název a popis pro pool. Vyberte jeden subnet, kde všichni členové tohoto poolu musí být. Vyberte protokol a metodu load balancing pro tento pool. Admin status je UP (zaškrtnuto) v základu."
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr "Přidat pool \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr "Nelze přidat pool \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr "VIP adresy z plovoucích IP"
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr "Persistentní relace"
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr "Název Cookie"
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr "Pro persistenci je vyžadováno APP_COOKIE; V jiném připadě ingnorujte."
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr "Limit připojení"
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr "Specifikovat volnou IP adresu z %s"
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr "Nastavit Session Persistence"
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr "V současnosti není podporováno "
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr "Přidat VIP"
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr "Vytvořte VIP (virtuální IP) pro tento pool. Přiřaďte název a popis pro VIP. Specifikujte IP adresu a port pro VIP. Vyberte protokol a metodu session persistence pro VIP. Specifikujte maximální povolený počet připojení. Admin status je UP (zaškrtnuto) v základu."
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr "Přidat VIP \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr "Nelze přidat VIP \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr "Pouze jedna adresa může být specifikována. Nelze přidat VIP %s."
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr "Nelze načíst pool."
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr "Jméno cookie musí být specifikovanáno v APP_COOKIE persistenci."
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr "Člen/Členové"
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr "Vyberte člena pro tento pool"
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr "závažnost"
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr "Vybrat pool"
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr "Nelze načíst seznam instancí."
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr "Žádné dostupné servery. Klikněte přidat pro zrušení."
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr "Detaily člena"
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr "Přidat člena to vybraného poolu\n\nVyberte jednu nebo více vypsaných instancí, které mají být přidány do poolu jako člen(ové). Přiřaďte číselnou závažnost. Specifikujte číslo portu na kterém bude člen(ové) operovat, např.:80."
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr "Přidán člen \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr "Nelze přidat člena %s."
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr "Žádné dostupné instance.%s"
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr "Nelze načíst seznam portů."
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr "Zpoždění"
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr "Timeout"
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr "Maximálně opakování (1~10)"
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr "Metoda HTTP"
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr "URL"
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr "Očekávané HTTP Status Codes"
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr "Vybrat typ"
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr "Vyberte metodu HTTP"
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr "Detaily monitoru"
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr "Vytvořit monitor pro pool\n\nVyberte pool a typ monitoru. Specifikujte zpoždění, timeout, a limit opakování. Vyberte metodu, URL cestu očekávaný HTTP kód."
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr "Přidán monitor \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr "Nelze přidat monitor \"%s\"."
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr "ID:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr "Tenant ID:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr "Pool ID:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr "Adresy:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr "Port protokolu:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr "Závažnost:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr "Admin status:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr "Status:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr "Typ:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr "Zpoždění:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr "Timeout:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr "Maximálně opakování:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr "Metoda HTTP:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr "URL cesta:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr "Očekávané kódy:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr "VIP ID:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr "Název:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr "Popis:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr "Subnet ID:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr "Protokol:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr "Metoda load balancing:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr "Členové:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr "Healt Monitory:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr "Persistentní relace:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr "Název Cookie:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr "Limity připojení:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr "Přidat nového člena"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr "Přidat nový monitor"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr "Přidat nový pool"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr "Specifikovat VIP"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr "Load balancer"
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr "Síťová topologie"
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr "Toto podokno potřebuje podporu JavaScriptu."
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr "Nejsou zde žádné sítě, routery nebo připojené instance k zobrazení."
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr "Přidat subnet"
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr "Nelze načíst detaily sítě."
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr "Název sítě. Toto pole je volitelné."
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr "Zde můžete vytvořit novou síť.\nKromě toho můžete připojit subnet do této sítě na následujícím panelu."
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr "Název subnetu"
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr "Název subnetu. Toto pole je volitelné."
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr "Síťové adresy"
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr "Síťová adresa v CIDR formátu (např.: 192.168.0.0/24)"
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr "IP brány (nepovinný)"
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr "IP adresa brány (např.: 192.168.0.254). Základní hodnota je první IP ze síťových adres (např.: 192.168.0.1 pro 192.168.0.0/24). Pokud chcete zanechat základní hodnotu, nechte pole prázdné. Pokud nechcete použít bránu, zaškrtněte \"Zakázat bránu\" níže."
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr "Zakázat bránu"
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr "Můžete vytvořit subnet připojený do nové sítě, v tomto příadě musí být specifikována \"Síťová adresa\". Pokud si přejete vytvořit síť BEZ subnetu, odškrtněte zaškrtávátko \"Vytvořit subnet\"."
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr "Specifikujte \"Síťová adresa\" nebo odškrtněte zaškrtávátko \"Vytvořit subnet\"."
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr "Síťová adresa a IP verze nejsou konzistentní."
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr "Subnet v síťové adrese je příliš malý (/%s)."
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr "IP brány a IP verze nejsou konzistentní."
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr "Specifikujte IP adresu brány nebo zaškrtněte \"Zakázat bránu\"."
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr "Povolit DHCP"
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr "Alokace Poolů"
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr "Alokace IP adresy poolů . Každý vstup &lt;start_ip_address&gt;,&lt;end_ip_address&gt; (např. 192.168.1.100,192.168.1.120) a jeden záznam na řádku."
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr "Název DNS serveru"
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr "Seznam IP adres DNS pro tento subnet. Jeden záznam na řádek."
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr "Host Routy"
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr "Další routy oznámení hostovi. Každý záznam je ve formátu &lt;destination_cidr&gt;,&lt;nexthop&gt; (např. 192.168.200.0/24,10.56.1.254) a jeden záznam na řádku."
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr "Můžete specifikovat další atributy pro subnet."
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr "%(field_name)s: špatná IP adresa (value=%(ip)s)"
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr "%(field_name)s: špatná IP adresa (value=%(network)s)"
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr "Počáteční a koncová adresa musí být specifikována (value=%s)"
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr "Počáteční adresa je vyšší než koncová (value=%s)"
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr "Chybný formát Host routy: Cílový CIDR a nexthop musí být specifikován (value=%s)"
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr "Vytvořit síť \"%s\"."
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr "Nelze vytvořit síť \"%s\"."
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr "Síť %s byla úspěšně vytvořena."
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr "Neúspěch při vytváření síťě \"%(network)s\": %(reason)s"
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr "Subnet \"%s\" byl úspěšně vytvořen."
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr "Neúspěch při vytváření subnetu \"%(sub)s\" pro síť \"%(net)s\": %(reason)s"
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr "Vymazat vytvořenou síť \"%s\" , jelikož vytváření subnetu selhalo."
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr "Nepodařilo se smazat sítě \"%s\""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr "Připojeno"
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr "Odpojeno"
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr "Připojené zařízení"
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr "Nelze načíst detaily portu"
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr "Nelze načíst detaily subnetu"
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr "Nelze načíst detaily subnetu"
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr "Můžete vytvořit subnet asociovaný se sítí. Upřesňující nastavení je dostupné v záložce o detailech subnetu."
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr "Vytvořit subnet \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr "Nelze vytvořit subnet \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr "IP adresy brány (např. 192.168.0.254). Potřebujete specifikovat explicitní adresu pro nastavení brány. Jestliže nechcete používat bránu, zaškrtněte dole pole \"Vypnout bránu\"."
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr "Můžete aktualizovat subnet asociovaný se sítí. Upřesňující nastavení je dostupné v záložce o detailech subnetu."
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr "Aktualizovat"
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr "Aktualizovaný subnet \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr "Nelze aktualizovat subnet \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr "Subnet \"%s\" byl úspěšně aktualizován."
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr "Nepodařilo se aktualizovat subnet \"%(sub)s\": %(reason)s"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr "Přehled sítě"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr "Síť poskytovatele"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr "Typ sítě"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr "Fyzická síť"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr "ID segmentace"
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr "Detail síťě:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr "Přehled portu"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr "Statická IP"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr "IP adresa:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr "ID subnetu"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr "MAC adresa"
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr "Detail portu"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr "Přehled subnetu"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr "IP verze"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr "Pool připojitelných IP"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr "Start"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr "- Konec"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr "Povolit DHCP"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr "Další routy"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr "Cíl"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ": Další skok"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr "Žádný"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr "DNS server"
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr "Detail subnetu"
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr "Router"
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr "Nelze vymazat router \"%s\""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr "Vyčistit"
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr "Vymazaný"
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr "Brána"
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr "Brány"
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr "Nelze vyčistit bránu routeru \"%(name)s\": \"%(msg)s\""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr "Nelze načíst detaily routeru."
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr "Nelze načíst seznam externích sítí \"%s\"."
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr "Externí síť \"%s\" nenalezena."
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr "Nelze načíst detaily routeru \"%s\"."
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr "Nelze načíst externí síť \"%s\"."
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr "Router ID"
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr "Chyba při získávání seznamu sítě %s"
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr "Vyvrat subnet"
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr "Žádné dostupné subnety."
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr "Interface přidán"
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr "Nemožné přidat interface %s"
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr "Vybrat síť"
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr "Žádné dostupné sítě."
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr "Brána pro interface je přidána"
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr "Neúspěšné nastavení brány %s"
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr "Interface"
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr "Selhalo mazání interface %s"
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr "Nelze načíst router."
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr "Nelze nastavit bránu."
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr "Velikost (GB)"
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr "Šifrování"
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr "Použít snapshot jako zdroj"
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr "Velikost svazku musí být stejná nebo větší než je velikost snapshotu (%sGB)"
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr "Nelze načíst specifikovaný snapshot."
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr "Vyberte snapshot"
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr "Velikost svazku nemůže být menší než velikost snapshotu (%sGB)"
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr "Svazek o velikosti %(req)iGB nemůže být vytvořen, protože máte dostupných pouze %(avail)iGB z vaší kvóty."
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr "Již využíváte všechny z vašich dostupných svazků."
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr "Nelze vytvořit svazek."
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr "Připojit do instance"
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr "Vyberte instanci do které chcete připojit."
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr "Neznámá instance (není)"
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr "Připojuji svazek %(vol)s do instance %(inst)s na %(dev)s."
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr "Nelze připojit svazek."
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr "Vytvářím snapshot svazku \"%s\""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr "Nelze vytvořit snapshot svazku."
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr "Nelze vymazat volume \"%s\". Jeden nebo více snapshotů na něm závísí."
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr "Upravit připojená zařízení"
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr "%sGB"
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr "Nemožné načíst informace o přílože."
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr "Připojeno do %(instance)s na %(dev)s"
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr "Odpojit"
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr "Odpojuji"
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr "%(dev)s na instanci %(instance_name)s"
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr "Nelze načíst detaily svazku."
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr "Nelze načíst seznam svazku."
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr "Nelze načíst informace o připojení svazku/instance."
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr "Nelze získat informace o svazku."
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr "Spravovat připojené svazky"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr "Připojit do instance"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr "Připojit svazek"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr "Svazek je blokové úložiště, které může být připojeno do instance."
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr " Kvóta svazku"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr "Celkem Gigabytes"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr "Počet svazků"
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr "Vytvořit snapshot svazku"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr "Přehled svazku"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr "Přípojky"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr "Není připojeno"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr "Metadata"
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr "Vytvořit svazek"
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr "Vytvořit snapshot svazku"
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr "Nastavení"
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr "Nastavení uložena."
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr "Uživatelské nastavení"
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr "Zde můžete upravovat nastavení dashboardu pro vašeho uživatele."
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Zakázáno"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Domů"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Stránka nenalezena"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "Stránka kterou hledáte, neexistuje"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "Možná jste napsali špatně adresu nebo stránka byla přesunuta."
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr "Chyba serveru"
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr "Něco je špatně!"
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr "Stala se neočekávaná chyba. Zkuste obnovit stránku. Pokud to nepomůže, kontaktujte administrátora."
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr "Nápověda"
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Přihlášen jako:"
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr "Odhlásit"
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr "Heslo musí mít od 8 do 18 znaků"
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr "Nelze načíst informace o využití."
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr "Díváte se na data z budoucnosti, které možná existují a možná ne."
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr "Stáhnout souhrn v CSV"
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr "VCPU hodiny"
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr "Jméno projektu"
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr "Disk GB hodiny"
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr "Souhrn využití"
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr "doba běhu"
diff --git a/openstack_dashboard/locale/en/LC_MESSAGES/django.mo b/openstack_dashboard/locale/en/LC_MESSAGES/django.mo
deleted file mode 100644
index 0cf60807..00000000
--- a/openstack_dashboard/locale/en/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/en/LC_MESSAGES/django.po b/openstack_dashboard/locale/en/LC_MESSAGES/django.po
deleted file mode 100644
index 46677a94..00000000
--- a/openstack_dashboard/locale/en/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4712 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Gabriel Hurley <gabriel@strikeawe.com>, 2012
-# johnpostlethwait <john.postlethwait@gmail.com>, 2012
-# johnpostlethwait <john.postlethwait@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: en\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr ""
-
-#: settings.py:153
-msgid "Czech"
-msgstr ""
-
-#: settings.py:154
-msgid "English"
-msgstr "English"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Spanish"
-
-#: settings.py:156
-msgid "French"
-msgstr "French"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Italiano"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Japanese"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr ""
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr ""
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Polish"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Portuguese"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr ""
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Simplified Chinese"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Traditional Chinese"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr ""
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr ""
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr ""
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr ""
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr ""
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr ""
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr ""
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr ""
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr ""
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Projects"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr ""
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr ""
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr ""
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr ""
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr ""
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Forbidden"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Home"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Page Not Found"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "The page you were looking for doesn't exist"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "You may have mistyped the address or the page may have moved."
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr ""
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/en_GB/LC_MESSAGES/django.mo b/openstack_dashboard/locale/en_GB/LC_MESSAGES/django.mo
deleted file mode 100644
index 0a6527bf..00000000
--- a/openstack_dashboard/locale/en_GB/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/en_GB/LC_MESSAGES/django.po b/openstack_dashboard/locale/en_GB/LC_MESSAGES/django.po
deleted file mode 100644
index ed8215f6..00000000
--- a/openstack_dashboard/locale/en_GB/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4711 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Andi Chandler <andi@gowling.com>, 2013
-# Andi Chandler <andi@gowling.com>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-05-04 21:47+0000\n"
-"Last-Translator: Andi Chandler <andi@gowling.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: en_GB\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "Bulgarian (Bulgaria)"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "Czech"
-
-#: settings.py:154
-msgid "English"
-msgstr "English"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Spanish"
-
-#: settings.py:156
-msgid "French"
-msgstr "French"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Italian"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Japanese"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "Korean (Korea)"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "Dutch (Netherlands)"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Polish"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Portuguese"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "Portuguese"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Simplified Chinese"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Traditional Chinese"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr "Unknown Instance"
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr "%(type)s (%(backend)s backend)"
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr "ALLOW %(from)s:%(to)s from %(group)s"
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr "ALLOW %(from)s:%(to)s from %(cidr)s"
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr "System Panel"
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "Admin"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "Name"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr "VCPUs"
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr "RAM MB"
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr "Root Disk GB"
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr "Ephemeral Disk GB"
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr "Created flavour \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr "Unable to create flavour."
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr "Updated flavour \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr "Unable to update flavour."
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr "Flavours"
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr "Flavour"
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr "Create Flavour"
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr "Edit Flavour"
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr "%sMB"
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr "Flavour Name"
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "RAM"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr "Root Disk"
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr "Ephemeral Disk"
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr "Unable to retrieve flavour list."
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr "Unable to retrieve flavour data."
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "Description"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr "From here you can define the sizing of a new flavour."
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "Cancel"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr "From here you can alter the sizing of the current flavour."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr "Note: this will not affect the resources allocated to any existing instances using this flavour."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr "Save"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "Images"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr "Image Name"
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr "Unable to retrieve image list."
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr "Description:"
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr "Update Image"
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr "From here you can modify different properties of an image."
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr "Host"
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr "Enabled"
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "Instances"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "Project"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr "IP Address"
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr "Size"
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr "Status"
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr "Task"
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr "Power State"
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr "Unable to retrieve instance list."
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr "Unable to retrieve instance tenant information."
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr "Unable to retrieve instance size information."
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr "All Instances"
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr "Admin State"
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr "Shared"
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr "Select a project"
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr "Network %s was successfully created."
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr "Failed to create network %s"
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr "ID"
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr "Network %s was successfully updated."
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr "Failed to update network %s"
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "Networks"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr "Network"
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr "Failed to delete network %s"
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr "Create Network"
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr "Edit Network"
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "Network Name"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr "Subnets Associated"
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr "Network list can not be retrieved."
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr "Subnet list can not be retrieved."
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr "Port list can not be retrieved."
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr "Unable to retrieve details for network \"%s\"."
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "Network ID"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr "Device ID"
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr "Port %s was successfully created."
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr "Failed to create a port for network %s"
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr "Port %s was successfully updated."
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr "Failed to update port %s"
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "Port"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "Ports"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr "Failed to delete subnet %s"
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr "Create Port"
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr "Edit Port"
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr "Fixed IPs"
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr "Device Attached"
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr "Overview"
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr "Unable to retrieve port details."
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr "Unable to retrieve network."
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr "Subnet"
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr "Subnets"
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr "Create Subnet"
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr "Edit Subnet"
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr "CIDR"
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr "IP Version"
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr "Gateway IP"
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr "Failed to retrieve network %s for a subnet"
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr "Select a name for your network."
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr "You may update the editable properties of your network here."
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr "Save Changes"
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr "Update Network"
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr "You can create a port for the network. If you specify device ID to be attached, the device specified will be attached to the port created."
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr "You may update the editable properties of your port here."
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr "Update Port"
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr "Network Detail"
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr "Update Subnet"
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr "Usage Overview"
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr "Monitoring"
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Projects"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr "Modify Users"
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr "View Usage"
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr "Create Project"
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr "Edit Project"
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr "Project ID"
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr "Remove"
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr "Removed"
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr "User"
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr "Users"
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr "Unable to retrieve role information."
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr "Roles"
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr "Users For Project"
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr "Add To Project"
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr "Add New Users"
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr "Unable to retrieve project information."
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr "Unable to retrieve project list."
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr "Unable to retrieve users."
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr "Unable to retrieve default quota values."
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr "Unable to retrieve project details."
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr "Injected File Content Bytes"
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr "Metadata Items"
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr "Injected Files"
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr "Volumes"
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr "Gigabytes"
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr "RAM (MB)"
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr "Floating IPs"
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr "Quota"
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr "From here you can set quotas (max limits) for the project."
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr "Project Info"
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr "From here you can create a new project to organise users."
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr "Unable to retrieve user list. Please try again later."
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr ""
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr ""
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr ""
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr ""
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr "Instance Name"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr "Network Address"
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr "Unable to retrieve port details"
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr "Unable to retrieve subnet details"
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr "IP version"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Forbidden"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Home"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Page Not Found"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "The page you were looking for does not exist"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "You may have mistyped the address or the page may have moved."
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr "Project Name"
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/es/LC_MESSAGES/django.mo b/openstack_dashboard/locale/es/LC_MESSAGES/django.mo
deleted file mode 100644
index e9c422d0..00000000
--- a/openstack_dashboard/locale/es/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/es/LC_MESSAGES/django.po b/openstack_dashboard/locale/es/LC_MESSAGES/django.po
deleted file mode 100644
index 51d65900..00000000
--- a/openstack_dashboard/locale/es/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4713 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Alberto Molina Coballes <alb.molina@gmail.com>, 2012-2013
-# Alberto Molina Coballes <alb.molina@gmail.com>, 2012
-# zeus <jonathan.abdiel@gmail.com>, 2012-2013
-# ladquin <laura.adq@gmail.com>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-05-02 16:32+0000\n"
-"Last-Translator: ladquin <laura.adq@gmail.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: es\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "Búlgaro (Bulgaria)"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "Checo "
-
-#: settings.py:154
-msgid "English"
-msgstr "Inglés"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Español"
-
-#: settings.py:156
-msgid "French"
-msgstr "Francés"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Italiano"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Japonés"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "Coreano (Corea)"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "Neerlandés (Países Bajos)"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Polaco"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Portugués"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "Portugués "
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Chino simplificado"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Chino tradicional"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr "Instancia Desconocida"
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr "%(type)s (%(backend)s backend)"
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr "PERMITIR %(from)s:%(to)s del %(group)s"
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr "PERMITIR %(from)s:%(to)s DESDE %(cidr)s"
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr "Panel de Sistema"
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "Administrador"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "Nombre"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr "VCPUs"
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr "RAM MB"
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr "Disco Raíz GB"
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr "Disco Efímero GB"
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr "Disco de swap MB"
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr "No ha sido posible obtener la lista de sabores"
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr "El nombre \"%s\" ya lo ha usado otro sabor."
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr "Sabor \"%s\" creado."
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr "No ha sido posible crear el sabor."
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr "Sabor \"%s\" actualizado."
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr "No ha sido posible actualizar sabor."
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr "Sabores"
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr "Sabor"
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr "Crear Sabor"
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr "Editar Sabor"
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr "Ver especif. extra"
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr "%sMB"
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr "Nombre del Sabor"
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "RAM"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr "Disco Raíz"
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr "Disco Efímero "
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr "Disco de swap"
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr "No ha sido posible obtener lista de sabores."
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr "No ha sido posible obtener datos del sabor."
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr "Clave"
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr "Valor"
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr "Se han creado las especif. extra \"%s\"."
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr "Se han guardado las especif. extra \"%s\"."
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr "ExtraSpec"
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr "Crear"
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr "Editar"
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "Descripción"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr "Desde aquí puede definir el tamaño del nuevo sabor."
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr "Desde aquí puede alterar el tamaño del sabor actual."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr "Nota: esto no afectara a los recursos reservados a las instancias que estén usando este sabor."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr "Guardar"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr "Cerrar"
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "Imágenes"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr "Nombre de la Imagen"
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr "No ha sido posible obtener la lista de imágenes."
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr "Crear una imagen"
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr "Descripción:"
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr "Especifique una imagen para subir al Servicio de Imágenes"
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr "Actualmente sólo es posible utilizar imágenes via una URL HTTP. El Servicio de Imágenes debe poder acceder a la ubicación de la imagen. Están soportadas imágenes binarias comprimidas (.zip and .tar.gz.)"
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr "Nota:"
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr "El campo de ubicación de la imagen DEBE ser una URL válida y directa al binario con la imagen. URLs con redirecciones o páginas de error producirán imágenes no usables."
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr "Crear imagen"
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr "Actualizar Imagen"
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr "Desde aquí puede modificar las diferentes propiedades de una imagen."
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr "Información del sistema"
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr "Nombre de la Cuota"
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr "Límite"
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr "Cuotas"
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr "Id"
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr "Servicio"
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr "Host"
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr "Habilitar"
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr "Servicios"
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr "Cuotas por Defecto."
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr "No es posible obtener la información de la cuota."
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "Instancias"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr "Migrar"
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr "Migración programada (pendiente de confirmación) de"
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr "Instancia"
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "Proyecto"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr "Dirección IP"
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr "Tamaño"
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr "Estado"
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr "Tarea"
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr "Estado de Energía"
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr "No ha sido posible obtener lista de instancias."
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr "No ha sido posible obtener la información de la instancia inquilina."
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr "No ha sido posible obtener la información del tamaño de la instancia."
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr "Todas las Instancias"
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr "Estado de la Administración"
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr "Compartido"
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr "Red externa"
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr "Seleccionar un proyecto"
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr "Se ha creado correctamente la red %s."
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr "Ha habido un fallo al crear red %s"
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr "ID"
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr "Se ha actualizado correctamente la red %s."
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr "Ha habido un fallo al actualizar la red %s"
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "Redes"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr "Red"
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr "Ha habido un fallo al eliminar red %s"
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr "Crear Red"
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr "Editar Red"
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "Nombre de la Red"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr "Subredes Asociadas"
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr "La lista de redes no pudo ser obtenida."
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr "La lista de subredes no pudo ser obtenida."
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr "La lista de puertos no pudo ser obtenida."
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr "No ha sido posible obtener los detalles de la red \"%s\"."
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "ID de la Red"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr "ID del Dispositivo"
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr "Propietario del dispositivo"
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr "El puerto %s fue creado con éxito. "
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr "Falló al crear un puerto para la red %s"
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr "El puerto %s fue actualizado con éxito."
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr "Falló al actualizar el puerto %s"
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "Puerto"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "Puertos"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr "Falló al borrar la subred %s"
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr "Crear Puerto"
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr "Editar Puerto"
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr "IPs Fijas"
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr "Dispositivo asociado"
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr "Vista General"
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr "Imposible obtener los detalles del puerto."
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr "Imposible obtener red."
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr "Subred"
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr "Subredes"
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr "Crear Subred"
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr "Editar Subred"
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr "CIDR"
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr "Versión IP"
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr "IP Puerta de Enlace"
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr "Fallo al obtener la red %s para la subred"
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr "Seleccione un nombre para su red"
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr "Aquí puede actualizar las propiedades editables de su red."
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr "Guardar Cambios"
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr "Actualizar Red"
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr "Puede crear un puerto para la red. Si especifica el ID del dispositivo para adjuntar, el dispositivo especificado será adjuntado al puerto creado."
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr "Aquí puede actualizar las propiedades editables de sus puertos."
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr "Actualizar Puerto"
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr "Detalles de la Red"
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr "Actualizar Subred"
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr "Vista General de Uso"
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr "Monitorización"
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Proyectos"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr "Modificar Usuarios"
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr "Ver Uso"
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr "Crear Proyecto"
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr "Editar Proyecto"
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr "ID del Proyecto"
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr "Eliminar"
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr "Eliminado"
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr "Usuario"
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr "Usuarios"
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr "No ha sido posible obtener la información del rol."
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr "Roles"
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr "Usuarios para el Proyecto"
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr "Agregar al Proyecto"
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr "Agregar Nuevo Usuario"
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr "Imposible obtener la información del proyecto."
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr "No ha sido posible obtener la lista de proyectos."
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr "No fue posible obtener los usuarios."
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr "No fue posible obtener los valores de cuota por defecto."
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr "No fue posible obtener los detalles del proyecto."
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr "Bytes contenido fichero inyectado"
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr "Ítems de metadatos"
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr "Ficheros inyectados"
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr "Volumenes"
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr "Gigabytes"
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr "RAM (MB)"
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr "IP Flotantes"
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr "Grupos de Seguridad"
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr "Reglas del Grupo de Seguridad"
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr "Cuota"
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr "Desde aquí puede asignar las cuotas (limites máximos) para el proyecto."
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr "Información del Proyecto"
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr "Desde aquí puede crear un nuevo proyecto para organizar los usuarios."
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr "Imposible obtener lista de usuarios. Por favor inténtelo más tarde"
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr "No se ha encontrado el rol por defecto \"%s\" en Keystone"
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr "Miembros del Proyecto"
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr "Todos los Usuarios"
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr "No se encontraron usuarios."
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr "No es posible obtener la lista de usuarios."
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr "Nuevo proyecto \"%s\" creado."
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr "Imposible crear proyecto \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr "Falló al agregar %s como miembro del proyecto y asignar las cuotas."
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr "No es posible asignar las cuotas del proyecto."
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr "Desde aquí puede editar los detalles del proyecto."
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr "Proyecto \"%s\" modificado."
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr "No ha sido posible modificar el proyecto \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr "No puede eliminar el rol \"admin\" del proyecto en el que está actualmente. Por favor seleccione otro proyecto con permisos de admin o borre el rol manualmente a través de la línea de comandos "
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr "Falló al modificar los miembros y las cuotas del proyecto %s"
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr "La información del proyecto y los miembros fueron modificados, pero no fue posible modificar las cuotas del proyecto."
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr "Agregar Usuario al Proyecto"
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr "Seleccione el rol del usuario para el proyecto."
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr "Agregar"
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr "Crear Usuario para el proyecto '%(tenant_name)s'."
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr "Desde aquí puede crear un nuevo usuario para agregar a este proyecto."
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr "Crear Usuario"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr "Actualizar Cuota"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr "Desde aquí puede editar las cuotas (limites máximos) para el proyecto %(tenant.name)s"
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr "Actualizar Proyecto"
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr "Desde aquí puede editar el proyecto."
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr "Desde aquí puede agregar y quitar miembros a este proyecto de la lista de todos los usuarios disponibles."
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr "Agregar Nuevo Usuario"
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr "Modificar Cuotas del Proyecto"
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr "Vista General de Uso del Proyecto"
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr "Uso del Proyecto"
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr "Usuarios del proyecto"
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr "Usuarios para el Proyecto."
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr "Nombre del encaminador"
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr "No ha sido posible obtener los tenants"
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr "Ha fallado la creación del encaminador \"%s\"."
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr "Crear encaminador"
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr "Encaminadores"
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr "No ha sido posible obtener la lista de encaminadores."
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr "Tipo"
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr "Interfaces"
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr "Crear encaminador"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr "Vista general de encaminador"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr "Información de la puerta de enlace exterior"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr "Red exterior conectada"
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr "Crear un encaminador"
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr "Detalles del encaminador"
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr "Detalles del encaminador"
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr "Añadir interfaz"
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr "Puede conectar una subred concreta al router."
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr "Añadir interfaz"
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr "Definir Puerta de enlace"
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr "Puede conectar una red exterior concreta al encaminador. Se considera la red exterior como la ruta por defecto del encaminador que actúa como puerta de enlace para la conexión exterior."
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr "Las contraseñas no coinciden"
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr "Nombre de Usuario"
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr "Correo"
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr "Contraseña"
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr "Confirmar Contraseña"
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr "Proyecto Principal"
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr "Rol"
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr "El usuario \"%s\" fue exitosamente creado."
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr "No es posible agregar el usuario al proyecto principal."
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr "No es posible crear el usuario."
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr "nombre"
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr "correo"
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr "proyecto principal"
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr "El usuario %s no tiene un rol definido para"
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr "contraseña "
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr "El usuario fue actualizado con éxito."
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr "No es posible actualizar %(attributes)s para el usuario."
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr "Habilitar"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr "Inhabilitar"
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr "Inhabilitado"
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr "No puede inhabilitar el usuario con el que está actualmente autenticado."
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr "ID Usuario"
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr "No fue posible actualizar el usuario."
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr "No es posible obtener la lista de roles."
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr "Desde aquí puede crear nuevos usuarios y asignarlos a un proyecto."
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr "Actualizar Usuario"
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr "Desde aquí puede editar los detalles del usuario incluyendo su proyecto por defecto."
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr "Se ha creado correctamente el tipo de volumen: %s"
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr "No ha sido posible crear el tipo de volumen."
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr "Crear Tipo de Volumen"
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr "Tipo de Volumen"
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr "Tipos de volúmenes"
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr "\nEl tipo de volumen define las características del volumen.\nNormalmente se corresponde con un conjunto de características del controlador de almacenamiento que se utiliza para este volumen.\nEjemplos: \"Rendimiento\", \"SSD\", \"Backup\", etc."
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr "Crear un Tipo de volumen"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr "Detalles del Volumen"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr "Detalle del Volumen"
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr "Administrar Compute"
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr "Almacén de Objetos"
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr "Acceso y Seguridad"
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr "No fue posible obtener los grupos de seguridad."
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr "Par de claves"
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr "No fue posible obtener la lista de pares de llaves."
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr "No fue posible obtener la lista de direcciones IP flotantes."
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr "No fue posible obtener los depósitos de IP flotantes."
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr "API de acceso"
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr "Descargar credenciales EC2"
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr "Descargar fichero RC de OpenStack"
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr "Endpoint de servicio"
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr "Endpoints de API"
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr "No ha sido posible obtener las credenciales EC2"
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr "Error al escribir el fichero zip: %(exc)s"
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr "Error al descargar fichero RC: %s"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr "Depósito"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr "IP Flotante %(ip)s asignadas."
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr "No fue posible asignar la IP Flotante"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr "Asignar IP al Proyecto"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr "Liberar"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr "Liberada"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr "IP Flotante"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr "Asociar IP Flotante"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr "Desasociar IP Flotante"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr "La IP Flotante: %s fue exitosamente desasociada"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr "No fue posible desasociar la IP flotante."
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr "Depósito de IP flotantes"
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr "No hay depósitos de IP flotantes disponibles"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr "Seleccione la dirección IP que desea asociar a la instancia seleccionada."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr "Puerto a asociar"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr "Instancia a asociar"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr "Seleccionar una dirección IP"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr "Hay direcciones IP disponibles"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr "Seleccione un puerto"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr "Seleccionar una instancia"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr "No hay puertos disponibles"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr "No hay instancias disponibles"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr "Manejar asociaciones de IP flotantes"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr "Asociar"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr "La dirección IP %s fue asociada."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr "No fue posible asociar la dirección IP %s."
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr "Nombre del Par de Claves"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr "El nombre del par de llaves debe contener solo letras, números, guiones bajos y guiones."
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr "Clave pública"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr "La clave: %s fue importada con éxito"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr "No fue posible importar el par de claves."
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr "Par de clave"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr "Importar par de claves"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr "Crear par de claves"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr "Fingerprint"
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr "No fue posible crear el par de claves: %(exc)s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr "Este campo es obligatorio"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr "La cadena sólo puede incluir caracteres ASCII y números."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr "El grupo de seguridad: %s fue creado con éxito"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr "No fue posible crear el grupo de seguridad."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr "Protocolo IP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr "TCP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr "UDP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr "ICMP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr "El protocolo al que esta regla debería ser aplicada."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr "Abrir"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr "Rango de puertos"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr "Introduzca un número entero entre 1 y 65535"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr "Desde Puerto"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr "Hasta Puerto"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr "Introduzca un valor para el tipo ICMP en el rango (-1:255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr "Código"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr "Introduzca un valor para el código ICMP en el rango (-1:255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr "Origen"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr "Grupo de Seguridad"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr "Para especificar un rango de IP permitidas, seleccione \"CIDR\". Para permitir acceso a todos los miembros de otro grupo de seguridad seleccione \"Grupo de Seguridad\""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr "Classless Inter-Domain Routing (p. ej. 192.168.0.0/24)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr "No hay grupos de seguridad disponibles"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr "El tipo ICMP no es valido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr "El código ICMP no es válido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr "El tipo ICMP no esta en el rango (-1,255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr "El código ICMP no esta en el rango (-1,255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr "El puerto especificado no es válido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr "El puerto \"desde\" no es valido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr "El puerto \"hasta\" no es valido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr "El numero del puerto \"hasta\" debe ser mayor o igual al numero del puerto \"desde\"."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr "Se agregó con éxito la regla: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr "No fue posible agregar la regla al grupo de seguridad."
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr "Crear Grupo de Seguridad"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr "Editar Reglas"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr "Agregar Regla"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr "Regla"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr "Reglas"
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr "No fue posible obtener el grupo de seguridad."
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr "%s (actual)"
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr "Acceso y Seguridad"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr "Asignar IP flotante"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr "Asignar una IP flotante de un depósito de IP flotantes dado"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr "Cuotas del Proyecto"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr "Asignar IP"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr "Los pares de claves son credenciales ssh que se inyectan en las imágenes cuando se lanzan. Al crear un nuevo par de claves se almacena la clave pública y se descarga la privada (un fichero .pem) "
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr "Proteja y use la clave como haría con una clave privada ssh"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr "Descargar par de claves"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr "El par de claves \"%(keypair_name)s\" debe descargarse automáticamente. Si esto no ocurre utilice el enlace siguiente."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr "Descargar el par de claves \"%(keypair_name)s\""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr "Las reglas definen el tráfico permitido a las instancias asociadas al grupo de seguridad. Una regla de un grupo de seguridad contiene tres pastes principales:"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr "Protocolo"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr "Debe especificar el protocolo IP para el que desea aplicar las reglas; las opciones son TCP, UDP o ICMP."
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr "Puerto Abierto/Rango de puertos"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr "Para las reglas de TCP y UDP puede optar por abrir un solo puerto o un rango de ellos. La opción \"Rango de puertos\" le proporcionará el espacio para especificar tanto el puerto de comienzo como de final del rango. Para las reglas de ICMP por el contrario debe especificar el tipo y código ICMP en los espacios proporcionados."
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr "Debe especificar el origen del tráfico a permitir a través de esta regla. Lo puede hacer bien con el formato de un bloque de direcciones IP (CIDR) o especificando un grupo de origen (Grupo de Seguridad). Al seleccionar un grupo de seguridad como origen, se permitirá que cualquier instancia de ese grupo de seguridad pueda acceder a cualquier otra instancia a través de esta regla."
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr "Desde aquí puede crear un nuevo grupo de seguridad"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr "Editar Reglas del Grupo de Seguridad"
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr "Swift"
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr "Contenedor"
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr "El \"slash\" / no es un carácter permitido."
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr "Nombre del Contenedor"
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr "Contenedor creado con éxito."
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr "Carpeta creada correctamente."
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr "No fue posible crear el contenedor."
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr "Nombre del Objeto"
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr "Se permiten los \"slashes\" que son tratados como seudo-carpetas por el Almacén de Objetos."
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr "Fichero"
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr "El Objeto fue cargado con éxito."
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr "No fue posible cargar el objeto."
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr "Contenedor de destino"
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr "Nombre del objeto de destino"
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr "Copiado \"%(orig)s\" a \"%(dest)s\" como \"%(new)s\"."
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr "No fue posible copiar el objeto."
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr "Contenedores"
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr "Crear Contenedor"
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr "Ver Contenedor"
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr "Subir Objeto"
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr "Objeto"
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr "Objetos"
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr "Copiar"
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr "Descargar"
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr "No ha sido posible obtener la lista de contenedores"
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr "No ha sido posible obtener la lista de objetos."
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr "No ha sido posible obtener el objeto."
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr "No ha sido posible listar los contenedores."
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr "Copiar Objeto"
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr "Hacer una nueva copia de un objeto existente en éste u otro contenedor. Debe especificar una ruta en el contenedor seleccionado para la nueva copia."
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr "Un contenedor es un compartimiento de almacenamiento de sus datos que proporciona una manera de organizarlos. Puede pensar que un contenedor es como una carpeta de Windows %reg; o un directorio en UNIX &reg;. La principal diferencia entre un contenedor y estos otros conceptos de sistemas de ficheros es que un contenedor no se puede anidar. Sin embargo, puede crear un número ilimitado de contenedores con su cuenta. Los datos deben almacenarse en un contenedor, por lo que al menos debe tener un contenedor definido en su cuenta antes de subir datos."
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr "Subir Objeto a Contenedor"
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr "Seudo-carpeta"
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr "En un contenedor puede agrupar sus objetos en seudo-carpetas, que se comportan de forma similar a las carpetas de su sistema operativo de escritorio, con la salvedad de que son colecciones virtuales definidas con un prefijo común en el nombre del objeto. Se utiliza el carácter \"slash\" (/) como delimitador de estas seudo-carpetas en el Almacén de Objetos."
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr "Subir Objetos"
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr "Imágenes e instantáneas"
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr "No ha sido posible obtener las imágenes"
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr "No ha sido posible obtener las instantáneas"
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr "No ha sido posible obtener las instantáneas de volúmenes."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr "Ubicación de la imagen"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr "Una (HTTP) URL externa desde la que cargar la imagen."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr "Fichero de imagen"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr "Formato"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr "AKI - Amazon Kernel Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr "AMI - Amazon Machine Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr "ARI - Amazon Ramdisk Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr "ISO - Imagen de disco óptico"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr "QCOW2 - Emulador QEMU"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr "Disco mínimo (GB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr "El tamaño mínimo de disco necesario para arrancar la imagen. Si no se especifica este valor se asume 0 (sin mínimo)."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr "Memoria mínima (MB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr "Público"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr "Debe especificar una imagen o una localización de la misma."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr "No se puede especificar una imagen y una ubicación externa a la vez."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr "Su imagen %s se ha puesto en cola para crearla."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr "No ha sido posible crear la nueva imagen."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr "Kernel ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr "Ramdisk ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr "Arquitectura"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr "No ha sido posible subir la imagen \"%s\"."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr "La imagen se actualizó correctamente."
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr "Lanzar"
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr "Imagen"
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr "No ha sido posible obtener los detalles de la imagen."
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr "No ha sido posible obtener la imagen."
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr "Instance ID"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr "Nombre de la instantánea"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr "Se ha creado la instantánea \"%(name)s\" de la instancia \"%(inst)s\""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr "No ha sido posible crear la instantánea."
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr "Instantánea"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr "Instantáneas"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr "Instantáneas de instancias"
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr "No ha sido posible obtener la instancia."
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr "Imágenes e Instantáneas"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr "Vista General de imágenes"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr "Info"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr "Suma de comprobación"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr "Creada"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr "Actualizada"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr "Detalles"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr "Formato de contenedor"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr "Formato de disco"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr "Propiedades personalizadas"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr "Estado de Euca2ools"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr "Tipo de imagen"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr "Detalles de la imagen"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr "Crear instantánea"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr "Las instantáneas conservan el estado de disco de una instancia en ejecución"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr "Volumen"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr "GB"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr "Crear instantánea"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr "Instantáneas de volumen"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr "Instantánea de volumen"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr "Instantánea de volumen"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr "Instantáneas de volumen"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr "Programado el borrado de"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr "Crear volumen"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr "Nombre del volumen"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr "No ha sido posible obtener las instantáneas."
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr "Terminar"
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr "Planificar la terminación de"
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr "Reinicio hard"
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr "Reiniciado hard"
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr "Reinicio soft"
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr "Reiniciado soft"
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr "Pausar"
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr "Reanudar"
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr "Pausada"
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr "Reanudada"
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr "Suspender"
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr "Suspendida"
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr "Lanzar Instancia"
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr "(Cuota superada)"
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr "Editar Instancia"
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr "Editar Grupos de Seguridad"
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr "Consola"
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr "Ver Log"
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr "Confirmar Redimensionar/Migrar"
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr "Deshacer Redimensionar/Migrar"
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr "Asociada correctamente la IP flotante: %s"
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr "No ha sido posible asociar la IP flotante."
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr "Se ha desasociado satisfactoriamente la IP Flotante: %s"
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr "No hay IPs flotantes que desasociar."
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disco"
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr "No disponible"
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr "Nombre de la Instancia"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr "Log"
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr "No ha sido posible obtener log de la instancia \"%s\"."
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr "No ha sido posible obtener las instancias."
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr "No ha sido posible obtener la consola VNC de la instancia \"%s\"."
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr "No ha sido posible obtener la consola de SPICE para la instancia \"%s\"."
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr "No ha sido posible obtener los detalles de las instancias."
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr "No ha sido posible obtener los detalles de la instancia \"%s\"."
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr "Consola de la instancia"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr "Si la consola no responde al teclado: haga click en la barra gris inferior."
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr "Haga click aquí para mostrar solo la consola"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr "No está disponible la consola actualmente. Por favor inténtelo de nuevo más tarde."
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr "Recargar"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr "Consola de Log de instancia"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr "Longitud del log"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr "Ir"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr "Ver Log Completo"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr "Vista General de instancias"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr "VCPU"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr "Disco"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr "Direcciones IP"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr "No hay reglas definidas."
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr "Meta"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr "Nombre de la clave"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr "Volúmenes asociados"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr "Asociado a"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr "en"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr "No hay volúmenes asociados"
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr "Se puede personalizar la instancia después de lanzarla utilizando las opciones disponibles aquí."
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr "El campo \"script personalizado\" es análogo a \"Datos de Usuario\" de otros sistemas."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr "Especifique los detalles de la instancia a lanzar"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr "La siguiente tabla muestra los recursos utilizados por este proyecto en relación a sus cuotas."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr "Detalle del sabor"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr "Disco total"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr "MB"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr "Número de instancias"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr "Número de VCPUs"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr "Memoria total"
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr "Seleccione una red de las disponibles a Redes Seleccionadas pulsando el botón o arrastrando y soltando, también se puede cambiar el orden de las nic mediante arrastrar y soltar."
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr "Se puede lanzar una instancia con distintos tipos de almacenamiento asociado. Debe seleccionar entre las opciones aquí."
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr "Redes seleccionadas"
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr "Redes disponibles"
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr "Detalles de la instancia"
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr "Proyecto y Usuario"
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr "No iniciar desde un volumen."
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr "Iniciar desde un volumen."
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr "Iniciar desde una instantánea de volumen (crea un nuevo volumen)"
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr "Opciones de volumen"
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr "Nombre de dispositivo"
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr "Punto de montaje del volumen (p. ej. 'vda' monta en '/dev/vda')."
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr "Borrar al Terminar"
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr "Borrar volumen al terminar la instancia"
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr "Por favor elija un volumen o seleccione %s."
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr "Seleccionar Volumen"
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr "No ha sido posible obtener la lista de volúmenes."
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr "Seleccionar Instantánea de volumen"
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr "No ha sido posible obtener la lista de instantáneas de volúmenes."
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr "Origen de la Instancia"
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr "Instantánea de Instancia"
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr "Tamaño de la imagen a lanzar"
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr "Total de instancias"
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr "Número de instancias a lanzar."
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr "Detalles"
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr "No hay imágenes origen disponibles; debe crear una imagen antes de intentar lanzar una instancia."
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr "Por favor seleccione una opción para el origen de la instancia"
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr "Lanzar múltiples instancias es posible sólo para imágenes e instantáneas de instancias."
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr "No ha sido posible obtener las imágenes públicas."
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr "No ha sido posible obtener imágenes para el proyecto actual."
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr "Seleccionar Imagen"
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr "No hay imágenes disponibles."
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr "Seleccionar instantánea de instancia"
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr "No hay instantáneas disponibles."
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr "No ha sido posible obtener los sabores de las instancias."
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr "No ha sido posible obtener información de cuotas."
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr "Qué par de claves usar para la autenticación."
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr "Lanzar la instancia en estos grupos de seguridad."
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr "Controle el acceso a sus instancias a través de los pares de claves, grupos de seguridad y otros mecanismos"
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr "No ha sido posible obtener los pares de claves."
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr "Seleccionar un par de claves"
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr "No hay pares de claves disponibles."
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr "No ha sido posible obtener la lista de grupos de seguridad"
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr "Script personalizado"
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr "Un script es un conjunto de instrucciones que se ejecutarán una vez la instancia haya sido generada (max 16kb)."
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr "Pos-creación"
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr "Debe especificar al menos una red."
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr "Lanzar instancia en estas redes"
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr "Redes"
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr "Seleccione las redes para su instancia"
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr "No ha sido posible obtener las redes."
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr "Lanzadas %(count)s de nombre \"%(name)s\"."
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr "No ha sido posible lanzar %(count)s de nombre \"%(name)s\"."
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr "%s instancias"
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr "instancia"
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr "No ha sido posible obtener la lista de grupos de seguridad. Pruebe más tarde."
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr "No se puede obtener la lista de grupos de seguridad actuales para la instancia %s."
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr "Desde aquí se pueden añadir o eliminar los grupos de seguridad de este proyecto de la lista de grupos de seguridad disponibles."
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr "Grupos de seguridad de la instancia"
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr "No se han encontrado grupos de seguridad."
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr "No hay grupos de seguridad activos."
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr "Desde aquí se puede editar los detalles de la instancia."
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr "Modificada la instancia \"%s\"."
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr "Balanceadores de carga"
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr "Añadir banco"
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr "Añadir Vip"
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr "Añadir miembro"
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr "Añadir monitor"
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr "Borrar"
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr "Vip"
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr "Vips"
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr "Bancos"
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr "Monitor"
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr "Monitores"
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr "Miembro"
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr "Miembros"
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr "VIP"
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr "Tipo de Monitor"
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr "No ha sido posible obtener la lista de bancos."
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr "No ha sido posible obtener la lista de miembros."
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr "No ha sido posible obtener la lista de monitores."
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr "Detalles del banco"
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr "No ha sido posible obtener los detalles del banco."
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr "Detalles de vip"
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr "No ha sido posible obtener los detalles de vip."
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr "Detalle de los miembros"
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr "No ha sido posible obtener los detalles de los miembros."
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr "Detalles de los monitores"
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr "No ha sido posible obtener los detalles de los monitores."
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr "No ha sido posible borrar el monitor."
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr "Debe borrar antes la Vip."
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr "No ha sido posible borrar el miembro."
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr "No ha sido posible localizar vip a borrar."
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr "No ha sido posible borrar vip."
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr "No ha sido posible obtener el banco de subredes."
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr "Método de balanceo de carga"
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr "Seleccionar una subred"
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr "No ha sido posible obtener la lista de redes."
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr "Seleccionar un protocolo"
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr "Detalles del banco"
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr "Crear un banco para el proyecto actual.\n\nAsignar un nombre y descripción al banco. Elegir una subred en la que deban estar todos los miembros de este banco. Seleccionar un protocolo y un método de balanceo de carga para este banco. El estado de Admin está activo (UP) por defecto."
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr "Añadidos los pools \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr "No ha sido posible agregar el banco \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr "Dirección vip desde IPs flotantes"
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr "Persistencia de sesión"
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr "Nombre de la Cookie"
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr "Necesario para APP_COOKIE persistence; ignorado en caso contrario."
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr "Límite de conexiones"
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr "Especificar una dirección IP libre desde %s"
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr "Definir persistencia de sesión"
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr "Actualmente no soportado"
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr "Añadir Vip"
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr "Crear una vip (IP virtual) para este banco. Asignar un nombre y una descripción a la vip. Especificar una dirección IP y un puerto a la vip. Seleccionar el protocolo y el método de persitencia de sesión para la vip. Especificar el máximo de conexiones permitidas. El estado de Admin está activo (UP) por defecto."
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr "Añadida Vip \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr "No ha sido posible agregar Vip \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr "Sólo se puede especificar una dirección. No ha sido posible añadir Vip %s."
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr "No ha sido posible obtener el banco."
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr "El nombre de la cookie se debe especificar con "
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr "Miembro(s)"
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr "Seleccione los miembros de este banco"
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr "Peso"
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr "Seleccionar un banco"
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr "No hay servidores disponibles. Haga click para cancelar."
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr "Añadir un miembro al banco seleccionado.\n\nSeleccionar una o más de las instancias listadas para añadirlas como miembros al banco. Asignar un peso numérico a este miembro. Especificar el número de puerto en el que el miembro opera; p. ej. 80."
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr "Demora"
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr "Timeout"
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr "Método HTTP"
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr "URL"
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr "Códigos de estado HTTP aceptados"
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr "Seleccionar método HTTP"
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr "Añadido Monitor \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr "ID: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr "Tenant ID: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr "Dirección:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr "Peso:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr "Estado:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr "Tipo:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr "Demora:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr "Timeout: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr "Método HTTP:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr "Ruta URL:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr "VIP ID: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr "Nombre:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr "Descripción:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr "ID de subred:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr "Protocolo:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr "Método de balanceo de carga:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr "Miembros:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr "Monitores de estado:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr "Persistencia de sesión:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr "Nombre de la Cookie:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr "Límite de conexiones:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr "Agregar un nuevo miembro"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr "Agregar un nuevo monitor"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr "Agregar un nuevo banco"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr "Especifique Vip"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr "Balanceador de carga"
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr "Topología de red"
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr "Este panel necesita soporte javascript."
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr "No hay redes, encaminadores o instancias conectadas que mostrar."
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr "Añadir subred"
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr "No ha sido posible obtener los detalles de la red."
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr "Nombre de red. Este campo es opcional."
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr "Desde aquí se puede crear una nueva red.\nAdicionalmente una subred asociada a esta red se puede crear en el siguiente panel."
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr "Nombre de subred"
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr "Nombre de subred. Este campo es opcional."
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr "Dirección de Red"
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr "Dirección de red en formato CIDR (p. ej. 192.168.0.0/24)"
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr "Dirección IP de la puerta de enlace (opcional)"
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr "Dirección IP de la puerta de enlace (p. ej. 192.168.0.254) El valor asumido es la primera dirección IP del rango (p. ej. 192.168.0.1 para la red 192.168.0.0/24). Si utiliza el valor asumido, deje el campo en blanco. Si no quiere utilizar puerta de enlace seleccione \"Deshabilitar puerta de enlace\" más abajo."
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr "Deshabilitar puerta de enlace"
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr "Se puede crear una subred asociada con la nueva red, en cuyo caso debe especificarse la \"dirección de red\". Si quiere crear una red SIN una subred, desmarque la opción \"Crear subred\"."
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr "Especifique \"Dirección de red\" o desactive la opción \"Crear subred\"."
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr "La dirección IP de la red y la versión IP no concuerdan"
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr "La subred es demasiado pequeña (/%s)."
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr "La dirección IP de la puerta de enlace y la versión IP no concuerdan"
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr "Especifique una dirección IP para la puerta de enlace o seleccione \"Deshabilitar puerta de enlace\"."
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr "Habilitar DHCP"
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr "Bancos de asignación"
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr "Bancos de direcciones IP a asignar. Cada entrada es &lt;dir_ip_inicio&gt;,&lt;dir_ip_fin&gt; (p. ej., 192.168.1.100,192.168.1.120) y una entrada por línea."
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr "Servidores DNS"
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr "Lista de direcciones IP de los servidores DNS para esta subred. Sólo uno por línea."
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr "Puede especificar atributos adicionales para la subred."
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr "Debe especificar las direcciones inicial y final (valor=%s)"
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr "La dirección final es mayor que la inicial (valor=%s)"
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr "Creada la red \"%s\"."
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr "No ha sido posible crear la red \"%s\"."
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr "La red \"%s\" ha sido creada correctamente."
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr "La subred \"%s\" ha sido creada correctamente."
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr "Fallo al borrar la red \"%s\""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr "Asociado"
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr "Desasociado"
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr "Dispositivo asociado"
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr "Imposible obtener los detalles del puerto."
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr "No ha sido posible obtener los detalles de la subred."
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr "Imposible obtener los detalles de la subred"
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr "Puede crear una subred asociada a la red. La configuración avanzada está disponible en la pestaña \"Detalle de subred\"."
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr "Se ha creado la subred \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr "No ha sido posible crear la subred \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr "Dirección IP de la puerta de enlace (p. ej. 192.168.0.254). Debe especificar una dirección concreta para configurar la puerta de enlace. Si no quiere utilizar puerta de enlace, seleccione \"Deshabilitar puerta de enlace\" más abajo."
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr "Actualizar"
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr "Subred \"%s\" actualizada."
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr "No ha sido posible actualizar la subred \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr "La subnet \"%s\" se ha actualizado correctamente."
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr "Fallo al actualizar la subred \"%(sub)s\": %(reason)s"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr "Vista General de redes"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr "Red de proveedor"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr "Tipo de red"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr "Red física"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr "Detalle de la red:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr "Vista General de puertos"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr "IP fija"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr "Dirección IP:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr "ID de subred"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr "Dirección MAC"
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr "Detalles de puerto"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr "Vista General de Subredes"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr "Versión IP"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr "Depósito de IP asignadas"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr "Comienzo"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr "- Final"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr "Rutas adicionales"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr "Destino"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ": Siguiente salto"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr "Ninguna"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr "servidor DNS"
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr "Detalle de subred"
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr "Encaminador"
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr "No ha sido posible borrar el router \"%s\""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr "Limpiar"
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr "Limpiado"
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr "Puerta de enlace"
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr "Puertas de enlace"
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr "No ha sido posible borrar la puerta de enlace del router \"%(name)s\": \"%(msg)s\""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr "No ha sido posible obtener los detalles del router."
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr "No se ha encontrado la red exterior \"%s\"."
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr "ID de router"
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr "Seleccionar subred"
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr "No hay subredes disponibles."
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr "Añadida la interfaz"
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr "Ha habido un fallo al agregar la interfaz %s"
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr "Seleccionar red"
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr "No hay redes disponibles."
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr "Interfaz"
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr "No ha sido posible definir la puerta de enlace."
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr "Tamaño (GB)"
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr "Cifrado"
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr "Utilizar una instantánea como origen"
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr "El tamaño del volumen debe ser igual o mayor que el de la instancia (%sGB)"
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr "No ha sido posible cargar la instantánea especificada."
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr "Seleccionar una instantánea"
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr "El tamaño del volumen no puede ser inferior al tamaño de la instantánea (%s GB)"
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr "No se puede crear un volumen de %(req)iGB porque sólo restan %(avail)iGB de su cuota."
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr "Ya está utilizando todos los volúmenes disponibles."
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr "No ha sido posible crear el volumen."
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr "Asociar a instancia"
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr "Seleccionar una instancia a la que asociar."
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr "Instancia desconocida (Ninguna)"
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr "Asociando el volumen %(vol)s a la instancia %(inst)s en %(dev)s"
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr "No ha sido posible asociar el volumen."
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr "Creando la instantánea del volumen \"%s\""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr "No ha sido posible crear la instantánea del volumen."
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr "No ha sido posible borrar el volúmen \"%s\". Uno o más snapshots dependen del mismo."
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr "Editar asociaciones"
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr "%sGB"
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr "No ha sido posible obtener información de la asociación."
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr "Asociado a %(instance)s en %(dev)s"
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr "Desasociar"
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr "Desasociando"
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr "%(dev)s de instancia %(instance_name)s"
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr "No ha sido posible obtener los detalles del volumen."
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr "No ha sido posible obtener la lista de volúmenes."
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr "No ha sido posible obtener información de la asociación volumen/instancia"
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr "No ha sido posible obtener la información del volumen."
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr "Administrar asociaciones de volumen"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr "Asociar a instancia"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr "Asociar volumen"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr "Los volúmenes son dispositivos de bloques que se pueden asociar a instancias."
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr "Cuotas de volúmenes"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr "Gigabytes totales"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr "Número de volúmenes"
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr "Crear instantánea de volúmen"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr "Vista General de volúmenes"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr "Asociaciones"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr "No asociado"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr "Metadatos"
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr "Crear un volumen"
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr "Crear una instantánea de volumen"
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr "Ajustes"
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr "Ajustes guardados"
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr "Ajustes de usuario"
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr "Desde aquí se puede cambiar los ajustes del usuario del panel de control."
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Prohibido"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Página de inicio"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Página no encontrada"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "La página que está buscando no existe"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "La dirección está mal escrita o la página se ha cambiado de sitio."
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr "Error del servidor"
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr "¡Algo fue mal!"
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr "Ha ocurrido un error inesperado. Pruebe a refrescar la página. Si esto no lo soluciona, contacte con su administrador local."
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr "Ayuda"
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Autenticado como"
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr "Salir"
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr "La contraseña debe tener entre 8 y 18 caracteres"
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr "No ha sido posible obtener la información de uso."
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr "Está viendo datos del futuro, que existirán o no."
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr "Descargar resumen en CSV"
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr "Horas VCPU"
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr "Nombre del Proyecto"
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr "Horas Disco GB"
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr "Resumen de uso"
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr "Uptime"
diff --git a/openstack_dashboard/locale/fi_FI/LC_MESSAGES/django.mo b/openstack_dashboard/locale/fi_FI/LC_MESSAGES/django.mo
deleted file mode 100644
index 80c44859..00000000
--- a/openstack_dashboard/locale/fi_FI/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/fi_FI/LC_MESSAGES/django.po b/openstack_dashboard/locale/fi_FI/LC_MESSAGES/django.po
deleted file mode 100644
index 7f2ce179..00000000
--- a/openstack_dashboard/locale/fi_FI/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4710 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# copard <ari.karhunen@pard.co>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-05-02 12:20+0000\n"
-"Last-Translator: copard <ari.karhunen@pard.co>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: fi_FI\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "Bulgaria"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "Tsekki"
-
-#: settings.py:154
-msgid "English"
-msgstr "Englanti"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Espania"
-
-#: settings.py:156
-msgid "French"
-msgstr "Ranska"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Italia"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Japani"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "Korea"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "Alankomaat"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Puola"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Portugali"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "Portugali (Brazilia)"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Pelkistetty Kiina"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Kiina"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr "Tuntematon instanssi"
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr "%(type)s (%(backend)s tausta)"
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr "SALLI %(from)s:%(to)s kohteesta %(group)s"
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr "SALLI %(from)s:%(to)s kohteesta %(cidr)s"
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr "Hallintapaneeli"
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "Admin"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "Nimi"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr "VCPU:t"
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr "RAM MB"
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr "Root Disk GB"
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr "Verkkolevy GB"
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr "Swap-levy MB"
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr "Ei voida hakea pohjamuottilistausta."
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr "Nimi \"%s\" on jo käytössä"
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr "Luotiin pohjamuotti \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr "Ei voida luoda pohjamuottia."
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr "Päivitettiin pohjamuotti \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr "Ei voida päivittää pohjamuottia."
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr "Pohjamuotit"
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr "Pohjamuotti"
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr "Luo Pohjamuotti"
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr "Muokkaa Pohjamuottia"
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr "Tarkastele lisäasetuksia"
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr "%sMB"
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr "Pohjamuotin Nimi"
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "RAM"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr "Root Disk"
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr "Verkkolevy"
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr "Swap Levy"
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr "Ei voida hakea listausta pohjamuoteista. "
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr "Ei voida hakea tietoja pohjamuotista."
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr "Avain"
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr "Arvo"
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr "Luotiin lisäoptio \"%s\"."
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr "Ei voida luoda pohjamuottia lisä spekseillä."
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr "Tallennettiin lisäoptio \"%s\"."
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr "Ei voida muokata lisä speksejä."
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr "Lisäoptio"
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr "LisäSpeksit."
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr "Luo"
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr "Muokkaa"
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr "Lisä Speksit"
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr "Ei oida hakea listausta lisä spekseistä. "
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr "Ei voida hakea pohjamuotin lisäoptioiden dataa."
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "Kuvaus"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr "Täältä voit määrittää uuden pohjamuotin koot."
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "Keskeytä"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr "Täältä voit muuttaa pohjamuotin kokoja. "
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr "HUOM: tämä ei vaikuta jo ajossa olevien instanssien resursseihin."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr "Tallenna"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr "Luo Pohjamuotti Lisäoptioilla. "
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr "Luo uusi \"Lisäoptio\" avain-arvopari pohjamuotille. "
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr "Muokkaa Pohjamuotin Lisäoptiota"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr "Päivitä pohjamuotin \"Lisäoptio\" avain-arvopari."
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr "Pohjamuotti Lisäoptioilla"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr "Sulje"
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "Levykuvat"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr "Levykuvan nimi"
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr "Ei voida hakea levykuvalistaa"
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr "Luo Levykuva"
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr "Kuvaus:"
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr "Määritä levykuva joka siirretään Levykuvapalveluun."
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr "Tällä hetkellä vain ne levykuvat ovat tuettu, jotka ovat saatavilla verkon kautta HTTP-URL:in kautta. Levykuvan täytyy löytyä kohteesta johonka Levykuvapalvelulla on pääsy. Pakatut kohteet kuten .zip ja .tar.gz ovat tuettu."
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr "Huomio:"
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr "Levykuvan kohdekentän täytyy sisältää toimiva URL-osoite levykuvan tiedostoon. URL-osoitteet jotka ohjaavat, tai tarjoavat virhesivun, johtaa toimimattomiin levykuviin. "
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr "Luo levykuva"
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr "Päivitä levykuva"
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr "Täältä voit muokata levykuvan arvoja"
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr "Järjestelmän Tiedot"
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr "Kiintiön nimi"
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr "Raja"
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr "Kiintiöt"
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr "Id"
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr "Palvelu"
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr "Isäntä"
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr "Päällä"
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr "Palvelut"
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr "Oletus kiintiöt"
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr "Ei voida hakea kiintiön tietoja"
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "Instanssit"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr "Muuta"
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr "Ajastettu muutto (odottaa vahvistusta)"
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr "Instanssi"
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "Projekti"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr "IP-osoite"
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr "Koko"
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr "Tila"
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr "Tehtävä"
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr "Virran Tila"
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr "Ei voida hakea instanssilistaa"
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr "Ei voida hakea instanssin asukastietoja"
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr "Ei voida hakea instanssin kokotietoja."
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr "Kaikki instanssit"
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr "Admin tila"
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr "Jaettu"
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr "Ulkoinen Verkko"
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr "Valitse projekti"
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr "Verkko %s luotiin onnistuneesti."
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr "Ei onnistuttu luomaan verkkoa %s"
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr "ID"
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr "Verkko %s päivitettiin onnistuneesti"
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr "Verkkoa %s ei onnistuttu päivittämään"
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "Verkko"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr "Verkot"
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr "Epäonnistuttiin verkon %s poistamisessa"
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr "Luo verkko"
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr "Muokkaa verkkoa"
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "Verkon nimi"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr "Assosioidut Aliverkot"
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr "Verkkolistausta ei voida hakea"
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr "Listaa aliverkoista ei voida hakea"
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr "Porttilistaa ei voida hakea."
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr "Ei voida hakea tarkempia tietoja verkosta \"%s\"."
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "Verkon ID"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr "Laitteen ID"
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr "Laitteen Omistaja"
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr "Portti %s luotiin onnistuneesti."
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr "Epäonnistuttiin portin luomisessa verkkoon %s"
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr "Portti %s päivitettiin onnistuneesti"
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr "Portin %s päivittämisessä epäonnistuttiin"
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "Portti"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "Portit"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr "Aliverkon %s poisto epäonnistui"
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr "Luo Portti"
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr "Päivitä Portti"
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr "Kiinteät IP:t"
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr "Liitetyt Laitteet"
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr "Yleiskatsaus"
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr "Ei voida hakea tarkempia tietoja portista."
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr "Ei voida hakea verkkoa."
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr "Aliverkko"
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr "Aliverkot"
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr "Luo Aliverkko"
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr "Muokkaa Aliverkkoa"
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr "CIDR"
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr "IP-versio"
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr "Oletusyhdyskäytävän IP"
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr "Epäonnistuttiin verkon %s hakemisessa aliverkolle."
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr "Valitse nimi verkolle."
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr "Voit päivittää verkon tietoja täällä."
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr "Tallenna muutokset"
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr "Päivitä verkko. "
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr "Voit luoda verkkoon portin. Jos määrität liitettävän laitteen ID:n, laite yhdistetään luotuun porttiin."
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr "Voit muokata portin tietoja täältä."
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr "Päivitä portti"
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr "Verkon tiedot"
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr "Päivitä aliverkko"
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr "Käytön yleiskatsaus"
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr "Monitorointi"
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Projektit"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr "Muokkaa käyttäjiä"
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr "Tarkkaile käyttöastetta"
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr "Luo projekti"
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr "Muokkaa projektia"
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr "projektin ID"
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr "Poista"
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr "Poistettu"
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr "Käyttäjä"
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr "Käyttäjät"
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr "Ei voida hakea rooli tietoja."
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr "Roolit"
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr "Projektin käyttäjät"
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr "Liitä projektiin"
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr "Lisää uusia käyttäjiä"
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr "Ei voida hakea projektin tietoja."
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr "Ei voida hakea projektilistausta."
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr "Ei voida hakea käyttäjiä."
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr "Ei voida hakea oletus kiintiöarvoja."
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr "Ei voida hakea projektin tietoja."
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr "Injektoidun tiedoston tavumäärä"
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr "Metadata kohta"
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr "Liitetyt tiedostot"
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr "Verkkolevyt"
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr "Gigabitit"
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr "RAM (MB)"
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr "Vapaat IP:t"
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr "Turvaryhmät"
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr "Turvaryhmän säännöt"
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr "Kiintiö"
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr "Täältä voit asettaa kiintiöt (maksimi rajat) projektille."
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr "Projektin tiedot"
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr "Täältä voit luoda uuden projektin."
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr "Ei voida hakea käyttäjälistaa. Yritä uudelleen myöhemmin."
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr "Ei löydetty roolia \"%s\" Keystone:sta"
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr "Projektin Jäsenet."
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr "Kaikki käyttäjät"
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr "Ei löydetty käyttäjiä. "
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr "Ei käyttäjiä."
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr "Ei voida hakea käyttäjälistaa."
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr "Luotiin uusi projekti \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr "Ei voida luoda projektia \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr "Epäonnistuttiin lisäämään %s projektiin käyttäjiä ja asettamaan projektin kiintiö."
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr "Ei voida asettaa projektin kiintiötä."
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr "Täältä voit muokata projektin asetuksia."
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr "Muokattiin projektia \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr "Ei voida muokata projektia \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr "Et voi poistaa \"admin\"-roolia projektista jossa olet juuri kirjautuneena sisään. Kirjaudu toiseen projektiin admin tunnuksin ja poista rooli käsin komentokehoitteen kautta. "
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr "Epäonnistuttiin %s projektin käyttäjien ja kiintiön muokkaamisessa. "
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr "Muokattiin projektin tietoja ja käyttäjiä, mutta epäonnistuttiin muokkaamaan projektin kiintiötä."
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr "Lisää käyttäjä projektiin."
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr "Valitse käyttäjärooli projektiin."
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr "Lisää"
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr "Luo käyttäjä projektiin '%(tenant_name)s'."
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr "Täältä voit luoda uuden käyttäjän ja asettaa hänet projektiin."
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr "Luo käyttäjä"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr "Päivitä kiintiötä"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr "Täältä voit muokata %(tenant.name)s projektin kiintiöitä."
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr "Päivitä projekti"
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr "Täältä voit päivittää projektia. "
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr "Täältä voit lisätä ja poistaa projektin käyttäjiä."
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr "Lisää uusi käyttäjä"
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr "Kuokkaa Projektin Kiintiöitä"
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr "Projektin käytön yleiskatsaus"
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr "Projektin käyttöaste"
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr "Projektin Käyttäjät"
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr "Projektin käyttäjät"
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr "Reitittimen Nimi"
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr "Asukkaiden hakemisessa epäonnistuttiin"
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr "Epäonnistuttiin reitittimen \"%s\" luomisessa."
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr "Luo Reititin."
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr "Reitittimet"
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr "Ei voida hakea listausta reitittimistä."
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr "Tyyppi"
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr "Portit"
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr "Luo reititin"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr "Reitittimen Yleiskatsaus"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr "Ulkoisen Oletusyhdyskäytävän Tiedot"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr "Yhdistä Ulkoiseen Verkkoon"
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr "Luo Reititin"
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr "Reitittimen Tiedot"
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr "Reitittimen Tiedot"
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr "lisää Portti"
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr "Voit liittää määritetyn aliverkon reitittimeen."
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr "Lisää Portti"
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr "Aseta Oletusyhdyskäytävä"
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr "Voit liittää määritetyn ulkoisen verkon reitittimeen. Ulkoinen verkko nähdään oletusreittinä reitittimelle ja reititin toimii yhdyskäytävänä virtuaalialiverkoille."
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr "Salasana ei täsmää"
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr "Käyttäjänimi"
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr "Sähköposti"
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr "Salasana"
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr "Vahvista Salasana"
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr "Päätoiminen projekti"
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr "Rooli"
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr "Käyttäjä \"%s\" luotiin onnistuneesti"
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr "Ei voida asettaa käyttäjää päätoimiseen projektiin."
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr "Ei voida luoda käyttäjää"
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr "nimi"
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr "sähköposti"
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr "päätoiminen projekti"
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr "käyttäjällä %s ei ole roolia määritelty"
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr "salasana"
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr "Käyttäjä päivitettiin onnistuneesti"
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr "Ei voida päivittää %(attributes)s käyttäjälle."
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr "aktivoi"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr "kytke pois"
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr "kytketty pois"
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr "Et voi kytkeä pois käyttäjää jona olet juuri kirjautuneena."
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr "käyttäjä-ID"
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr "Ei voida päivittää käyttäjää."
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr "Ei voida hakea käyttäjärooleja."
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr "Täältä voit luoda uuden käyttäjän ja asettaa projektiin."
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr "Päitivä käyttäjä."
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr "Täältä voit päivittää käyttäjän tietoja, mukaanlukien oletusprojektin."
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr "Onnistuneesti luotiin verkkolevyn tyyppi: %s"
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr "Ei voida luoda verkkolevyn tyyppiä. "
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr "Luo Verkkolevyn Tyyppi"
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr "Verkkolevyn Tyyppi"
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr "Verkkolevyn Tyypit"
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr "Ei voida hakea verkkolevyn omistajan tietoja."
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr "Ei voida hakea verkkolevyjen tyyppejä"
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr "\nPohjamuotin tyyppi määrittää pohjamuotin attribuutit.\nTämä yleensä määrittää kuinka taustalla oleva verkkolevy toimii, ja millaisia \"kykyjä\" verkkolevyllä on. \nEsim: Suorituskyky, SSD, varmuuskopiot, ym. "
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr "Luo Verrkolevyn tyyppi"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr "Verkkolevyn Tiedot"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr "Verkkolevyn tiedot"
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr "Hallinnoi Virtuaalikonetta"
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr "Object Store"
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr "Pääsy & Turvaus"
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr "Ei voida hakea turvaryhmiä."
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr "Avainparit"
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr "Ei voida hakea avainparilistaa."
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr "Ei voida hakea vapaita IP-osoitteita."
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr "Ei voida hakea vapaiden IP-osoitteiden varantoa."
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr "API-yhteys"
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr "Lataa EC2-tunnukset"
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr "Lataa OpenStack RC-tiedosto."
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr "Palvelun päätepiste"
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr "API-päätepiste"
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr "Ei voida hakea EC2-tunnuksia"
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr "Virhe kirjoittaessa zip-tiedostoa: %(exc)s"
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr "Virhe ladatessa RC-tiedostoa: %s"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr "varanto"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr "Asetettiin vapaa IP %(ip)s."
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr "Ei voida asettaa vapaata IP:tä."
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr "Allokoi projektille IP."
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr "Irroita"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr "Irroitettu"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr "Vapaa IP"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr "Assosioi vapaa IP"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr "Irroita vapaa IP"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr "Onnistuneesti irroitettiin vapaa IP: %s"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr "Ei voida irroittaa vapaata IP:tä."
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr "Vapaiden IP-osoitteiden varanto"
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr "Ei vapaita IP-osoitevarantoja saatavilla."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr "Valitse IP-osoite jonka haluat asettaa instanssille."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr "Portti assosioitu"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr "Assosioitu Instanssi"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr "Valitse IP-osoite"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr "Ei IP-osoitteita saatavilla"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr "Valitse portti"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr "Valitse instanssi"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr "Ei portteja saatavilla"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr "Ei instansseja saatavilla"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr "Hallinnoi vapaiden IP-osoitteiden liittämistä."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr "Liitä"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr "IP-osoite %s liitetty."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr "Ei voida liittää IP-osoitetta %s."
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr "Avainparin nimi"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr "Avainparin nimi voi sisältää vain kirjaimia, numeroita, alaviivoja ja väliviivoja. Ei åöä. "
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr "Julkinen Avain"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr "Onnistuneesti tuotiin julkinen avain: %s"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr "Epäonnistuttiin avainparin tuomisessa."
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr "Avainpari"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr "Tuo avainpari"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr "Luo Avainpari"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr "Sormenjälki"
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr "Ei voida luoda avainparia: %(exc)s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr "Tämä kenttä vaaditaan."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr "Rimpsu voi sisältää vain ASCII-merkkejä ja -numeroita."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr "Luotiin onnistuneesti turvaryhmä: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr "Ei voida luoda turvaryhmää."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr "IP-protokolla"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr "TCP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr "UDP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr "ICMP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr "Protokolla johonka tämä sääntö asetetaan."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr "Avoin"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr "Portiväli"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr "Anna arvo väliltä 1 - 65535"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr "Portista"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr "Porttiin"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr "Lisää arvo ICMP-tyypille (-1: 255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr "Koodi"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr "Lisää arvo ICMP-tyypille (-1: 255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr "Lähde"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr "Turvaryhmä"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr "Määrittääksesi sallitun IP-avaruuden, valitse \"CIDR\". Salliaksesi pääsyn kaikilta toisen turvaryhmän jäseniltä, valitse \"Turvaryhmä\"."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr "Luokaton reitti (esim, 192.168.0.0/24)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr "Ei turvaryhmiä saatavilla."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr "ICMP-tyyppi on väärin."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr "ICMP-koodi on väärin."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr "ICMP-tyyppi ei ole väliltä -1 - 255."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr "ICMP-koodi ei ole väliltä -1, 255."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr "Määritetty portti on väärin. "
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr "Lähdeportti on väärin."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr "Kohdeportti on väärin."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr "Kohdeportin arvo pitää olla sama tai suurempi kuin lähdeportin."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr "Onnistuneesti lisättiin sääntö: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr "Ei voida asettaa sääntöä turvaryhmään."
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr "Luo Turvaryhmä"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr "Muokkaa sääntöjä"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr "Lisää Sääntö"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr "Sääntö"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr "Säännöt"
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr "Ei voida hakea turvaryhmää."
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr "%s (nykyinen)"
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr "Pääsy &amp; Turvaus"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr "Aseta vapaa IP"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr "Aseta vapaa IP vapaiden osoitteiden ryhmästä."
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr "Projektin Kiintiöt"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr "Aseta IP"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr "Avainparit ovat ssh-tunnuksia jotka lisätään käynnistettävään levykuvaan. Kun uusi avainpari luodaan, rekisteröi julkinen avain ja lataa yksityinen avain (.pem tiedosto)."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr "Suojaa ja käytä avainta kuten muitakin hallussasi olevia ssh-privaattiavaimia."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr "Lataa Avainpari"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr "Avainpari &quot;%(keypair_name)s&quot; pitäisi lähteä latautumaan automaattisesti, jos ei, käytä alla olevaa linkkiä."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr "Lataa avainpari &quot;%(keypair_name)s&quot;"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr "Säännöt määrittävät mikä liikenne on sallittua instanssille, joka on liitetty turvaryhmään. Turvaryhmään liitettävä sääntö koostuu kolmesta pääkomponentista:"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr "Protokolla"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr "Sinun täytyy määrittää haluttu IP-protokolla johonka sääntö määritetään. Mahdolliset optiot ovat TCP, UDP tai ICMP."
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr "Avaa Portti/Portteja"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr "Jokaiselle TCP- ja UPD-säännölle voit joko avata yhden tai useamman portin. Valitessasi \"Porttiväli\"-option, tämä avaa sinulle mahdollisuuden valita porttivälin alkuportin ja loppuportin porttivälille. ICMP-säännöille voit määrittää ICMP-tyypin ja koodin. "
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr "Sinin täytyy määrittää liikenteen lähde joka sallitaan tällä säännöllä. Voit valita joko IP-osoiteavaruuden tai turvaryhmän. Valitessasi turvaryhmän lähteeksi, toiset instanssit kyseisessä ryhmässä voivat olla yhteydessä instanssiin. "
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr "Täältä voit luoda uuden turvaryhmän."
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr "Muokkaa turvaryhmän sääntöjä."
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr "Swift"
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr "Kontti"
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr "Kauttaviiva ei ole sallittu merkki."
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr "Kontin Nimi"
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr "Kontti luotiin onnistuneesti."
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr "Kansio luotiin onnistuneesti."
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr "Konttia ei voida luoda."
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr "Objektin Nimi"
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr "Kauttaviivat ovat sallittuja ja niitä käsitellään pseudokansioina Object Store:ssa."
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr "Tiedosto"
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr "Objekti siirrettiin onnistuneesti."
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr "Ei voida siirtää objektia."
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr "Kohde kontti."
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr "Objektin kohde nimi"
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr "Kopioitiin \"%(orig)s\" kohteeseen \"%(dest)s\" nimellä \"%(new)s\"."
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr "Objektia ei voida kopioida."
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr "Kontit"
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr "Luo Kontti"
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr "Näytä Kontti"
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr "Siirrä Objekti"
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr "Objekti"
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr "Objektit"
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr "Kopioi"
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr "Lataa"
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr "Ei voida hakea konttilistausta."
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr "Ei voida hakea objektilistausta."
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr "Ei voida hakea objektia."
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr "Ei voida listata kontteja."
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr "Kopioi Objekti."
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr "Luo uusi kopia objektista jonka voit tallettaa toiseen konttiin. Voit halutessasi myös tarkentaa polun jonnekka kopio asetetaan. "
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr "Kontti on tallennuskohde tiedostoillesi ja mahdollistaa datan organisoimisen. Voit kuvitella kontin olevan kuin kansio Windows&reg;-ymäristössä, tai hakemisto UNIX&reg;:ssa. Suurin ero kuitenkin kontin ja kansion välillä on, että kontin sisälle ei voida luoda uusia kontteja, mutta voit luoda rajattoman määrän kontteja tunnuksellesi. Tieto täytyy säilyttää kontin sisällä, joten sinulla on oltava vähintään yksi kontti määritettynä ennen tietojen lataamista ympäristöön. "
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr "Siirrä Objekti Konttiin"
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr "Objekti on perus varaston entiteetti joka edustaa tiedostoa jonka asetat OpenStack:in Object Storage ympäristöön. Kun siirrä tietoa OpenStack Object Storage:en, tieto tallenetaan sellaisenaan (ei pakkausta eikä salausta), sisältää tiedon kohteesta (kontti), objektin nimen ja metadatan sisältäen avain/arvo parit."
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr "Pseudo-kansio"
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr "Kontin sisällä voit ryhmitellä tiedostojasi pseudo-kansioihin, jotka käyttäytyvät samalla tavalla kuin kansiot työpöytäkäyttöjärjestelmässä, sillä erolla että ne ovat virtuaalisia ryhmiä, jotka ovat määritelty yhteisellä objektin nimen alkuosalla. Kauttaviiva (/) merkkiä käytetään pseudokansioiden jakajana Object Storessa. "
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr "Siirrä Objektit"
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr "Levykuvat & Vermuusvedokset"
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr "Ei voida hakea levykuvia."
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr "Ei voida hakea varmuusvedoksia."
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr "Ei voida hakea levyjaon varmuusvedosta."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr "Levykuvan Sijainti"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr "Ulkoinen osoite (HTTP), josta levykuva ladataan."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr "Levykuvan Tiedosto"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr "Formaatti"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr "AKI - Amazon Kernel Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr "AMI - Amazon Machine Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr "ARI - Amazon Ramdisk Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr "ISO - Optical Disk Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr "QCOW2 - QEMU Emulator"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr "Levyn Vähimmäiskoko (GB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr "Vaadittu tila virtuaalikovalevyltä jotta levykuva voidaan käynnistää. Jos arvoa ei ole määritelty, oletuksena on 0, tarkoittaen vaadittua minimikokoa. "
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr "Vähimmäis RAM (MB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr "Julkinen"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr "Levykuva tai ulkoisen levyn kohde täytyy määrittää."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr "Molempia ei voida määrittää, levykuva ja ulkoinen kohde. "
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr "Levykuva %s on asetettu jonoon odottamaan luontia."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr "Ei voida luoda uutta levykuvaa."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr "Kernel ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr "Ramdisk ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr "Arkkitehtuuri"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr "Levykuvaa \"%s\" ei voida päivittää."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr "Levykuva päivitettiin onnistuneesti."
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr "Laukaise"
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr "Levykuva"
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr "Ei voida hakea levykuvan tietoja."
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr "Ei voida hakea levykuvaa."
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr "Instanssin yksilöintitunnus."
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr "Varmuusvedoksen Nimi"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr "Varmuusvedos \"%(name)s\" luotiin instanssille \"%(inst)s\""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr "Varmuusvedoksen luonti epäonnistui."
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr "Varmuusvedos"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr "Varmuusvedokset"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr "Instanssin Varmuusvedokset"
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr "Ei voida hakea instanssia."
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr "Levykuvat &amp; Varmuusvedokset"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr "Levykuvien yleiskatsaus"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr "Info"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr "Tarkistesumma"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr "Luotu"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr "Päivitetty"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr "Tarkat tiedot"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr "Kontin formaatti"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr "Levyn Formaatti"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr "Mukautetut arvot"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr "Euca2ools:in tila"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr "Levykuvan Tyyppi"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr "Levykuvan Tiedot"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr "Luo Varmuusvedos"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr "Varmuusvedokset talleantavat ajossa olevan instanssin tilan. "
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr "Verkkolevy"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr "GB"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr "Luo varmuusvedos"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr "Verkkolevyn Varmuusvedokset Tiedot"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr "Verkkolevyn Varmuusvedokset Tiedot"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr "Verkkolevyn Varmuusvedos"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr "Verkkolevyn Varmuusvedokset"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr "Aikataulutettiin tuhoaminen,"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr "Luo Verkkolevy"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr "Verkkolevyn Nimi"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr "Ei voida hakea varmuusvedoksen tietoja."
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr "Tuhoa"
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr "Aikatalutettiin tuhaminen kohteelle"
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr "Kova Uudelleenkäynnistäminen"
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr "Kovasti Uudelleenkäynnistetty"
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr "Pehmea Uudelleenkäynnistäminen"
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr "Pehmesti Uudelleenkäynnistetty"
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr "Pysäytä"
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr "Palauta"
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr "Pysäytetty"
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr "Palautettu"
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr "Jäädytä"
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr "Jäädytetty"
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr "Laukaise Instanssi"
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr "(Kiintiö ylitetty)"
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr "Muokkaa Instanssia"
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr "Muokkaa Turvaryhmiä"
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr "Konsoli"
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr "Näytä Logi"
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr "Vahvista Koon muutos / Siirto"
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr "Palauta Koon muutos / Siirto"
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr "Onnistuneesti liitettiin vapaa IP: %s"
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr "Ei voida liittää vapaata IP:tä."
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr "Onnistuneesti irroitettiin vapaa IP. %s"
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr "Ei vapaita IP:tä poistettavaksi. "
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr "Ei saatavilla"
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr "Instanssin nimi"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr "Logi"
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr "Ei voida hakea logia instanssille \"%s\"."
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr "Ei voida hakea instansseja."
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr "Ei voida hakea VNC-konsolia instanssille \"%s\"."
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr "Ei voida hakea SPICE-konsolia instanssille \"%s\"."
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr "Ei voida hakea instanssin tietoja."
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr "Ei voida hakea instanssin \"%s\" tietoja."
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr "Instanssin Konsoli"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr "Jos konsoli ei vastaa näppäimistön komentoihin: klikkaa alla olevaa harmaata tilannetolppaa. "
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr "Paina täältä näyttääksesi vain konsolin."
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr "Konsoli ei ole juuri nytten saatavilla. Yritä uudelleen myöhemmin. "
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr "Lataa uudellen"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr "Instanssin Konsoli Logi"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr "Login Pituus"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr "Mene"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr "Näytä koko logi"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr "Instanssin yleiskatsaus"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr "VCPU"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr "Levy"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr "IP-osoitteet"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr "Ei määriteltyjä sääntöjä."
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr "Meta"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr "Avaimen Nimi"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr "Liitetyt Verkkolevyt"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr "Liitetty kohteeseen"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr "päällä"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr "Verkkolevyjä ei liitettynä."
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr "Voit kustomoida instanssia laukaisun jälkeen täällä olevilla optioilla. "
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr "\"Kustomointi Skripti\" kenttä tarkoittaa \"User Data / Käyttäjä Dataa\" toisissa järjestelmissä. "
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr "Määritä instanssin laukaisun yksityiskohdat."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr "Alapuolella oleva kuvaaja näyttää projektin käytetyt resurssit suhteessa projektin kiintiöön."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr "Pohjamuotin Tiedot"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr "Levytila yhteensä."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr "MB"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr "Instanssien Määrä"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr "VCPU:t määrä"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr "RAM yhteensä"
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr "Valitse verkko saatavilla olevista verkoista."
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr "Instanssiin voidaan liittää laukaistaessa eri kokoisia verkkolevyjä. Voit valita tämän täältä. "
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr "Valitut Verkot"
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr "Saatavilla olevat verkot"
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr "Instanssin tiedot."
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr "Projekti & Käyttäjät"
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr "Ei käynnistetä verkkolevyltä. "
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr "Käynnistä verkkolevyltä."
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr "Käynnistä verkkolevyn varmuusvedokselta (luo uuden verkkolevyn)."
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr "Verkkolevyn Optiot. "
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr "Laitteen Nimi"
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr "Verkkolevyn liittämiskohta (esim, 'vda' kiinnittyy kohteeseen '/dev/vda/')"
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr "Poista tuhotessa Instanssia"
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr "Tuhoa verkkolevy kun instanssi tuhotaan."
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr "Valitse verkkolevy tai valitse %s."
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr "Valitse Verkkolevy"
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr "Ei voida hakea listausta verkkolevyistä. "
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr "Valitse Verkkolevyn varmuusvedos"
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr "Ei voida hakea listausta verkkolevyn varmuusvedoksista. "
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr "Instanssin Lähde."
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr "Instanssin Varmuusvedos"
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr "Laukaistavan levykuvan koko. "
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr "Instanssien määrä"
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr "Kuinka monta instanssia laukaistaan."
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr "Tarkat Tiedot"
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr "Levykuvia ei ole saatavilla. Sinun täytyy luoda ensin levykuva, ennen kuin yrität laukaista instanssia."
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr "Valitse optiot instanssin lähteeksi. "
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr "Usean instanssin laukaisu on tuettu vain laukaistessa levykuvia tai instanssien varmuusvedoksia. "
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr "Ei voida hakea julkisia levykuvia."
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr "Ei voida hakea levykuvia nykyiselle projektille. "
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr "Valitse Levykuva"
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr "Ei levykuvia saatavilla. "
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr "Valitse Instanssin Varmuusvedos"
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr "Ei varmuusvedoksia saatavilla. "
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr "Ei voida noutaa instanssin pohjamuottia."
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr "Ei voida hakea kiintiön tietoja."
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr "Mitä avainparia käytetään varmentamiseen."
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr "Laukaise instanssi tässä turvaryhmässä."
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr "Hallitse pääsyä instanssille avainpareilla, turvaryhmillä, ja toisilla mekanismeilla. "
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr "Ei voida hakea avainpareja. "
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr "Valitse avainpari."
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr "Ei avainpareja saatavilla."
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr "Ei voida hakea listausta turvaryhmistä. "
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr "Kustomointi Skripti"
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr "Skripti tai komentoja jotka ajetaan kun instanssi on rakennettu (maksimi 16kb)."
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr "Jälkiluonti"
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr "Ainakin yksi verkko pitää olla määritettynä."
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr "Laukaise instanssi näissä verkoissa."
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr "Luodaan Verkkoasetuksia"
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr "Valitse verkko instanssille."
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr "Ei voida hakea verkkoja. "
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr "Laukaistiin %(count)s nimellä \"%(name)s\""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr "Ei voida laukaista %(count)s nimellä \"%(name)s\""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr "%s instanssit"
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr "instanssi"
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr "Ei voida hakea listausta turvaryhmistä. Yritä uudelleen myöhemmin."
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr "Ei voitu hakea nykyistä turavryhmää instanssille %s."
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr "Epäonnistuttiin instanssin %d turvaryhmien muokkaamisessa."
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr "Täältä voit lisätä ja poistaa turvaryhmiä tähän projektiin listalla olevista turvaryhmistä. "
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr "Kaikki Turvaryhmät"
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr "Instanssin Turvaryhmät"
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr "Ei turvaryhmiä löydetty."
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr "Ei turvaryhmiä laitettu päälle."
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr "Täältä voit muokta virtuaalikoneen tietoja."
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr "Muokattiin instanssia \"%s\"."
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr "Ei voida muokata instanssia \"%s\"."
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr "Kuormantasaajat"
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr "lisää Varanto"
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr "Lisää Vip"
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr "Lisää Jäsen"
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr "Lisää Monitori"
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr "Poista"
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr "Vip"
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr "Vipit"
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr "Varannot"
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr "Monitori"
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr "Monitorit"
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr "Jäsen"
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr "Jäsenet"
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr "VIP"
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr "Protokollan Portti"
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr "Monitorin Tyyppi"
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr "Ei voida hakea listausta varannoista. "
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr "Ei voida hakea listausta jäsenistä. "
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr "Ei voida hakea listausta monitoreista. "
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr "Varannon Tiedot"
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr "Ei voida hakea tietoja varannosta. "
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr "VIP tiedot"
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr "Ei voida hakea vip tietoja. "
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr "Jäsenen Tiedot"
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr "Ei voida hakea tietoja jäsenestä. "
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr "Monitorin Tiedot"
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr "Ei voida hakea tietoja monitorista. "
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr "Ei voida poistaa monitoria. "
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr "Sinun täytyy tuohota Vip ensin."
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr "Ei voida poistaa jäsentä. "
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr "Ei voida kohdentaa poistettavaa VIP:iä."
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr "Ei voida poistaa VIP:"
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr "Ei voida hakea aliverkon varantoa. "
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr "Kuormantasausmetodit"
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr "Valitse Aliverkko"
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr "Ei voida hakea listausta verkoista. "
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr "Valitse Protokolla"
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr "VarannonTiedot"
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr "Luo varanto nykyiselle asukkaalle\n\nAseta nimi ja kuvaus varantoon. Valitse aliverkko missä kaikkien jäsenten on oltava. Valitse protokolla ja kuormantasausmetodi tälle varannolle. Admin Tila on päällä (ruksattuna) oletuksena."
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr "Lisättiin Varanto \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr "Ei voida lisätä varantoa \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr "VIP-Osoitteet Vapaista IP:stä"
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr "Yhteyden Säntillisyys"
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr "Keksin Nimi"
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr "Vaaditaan APP_COOKIE persitence; muuten jätetään huomiotta."
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr "Avoimien yhteyksien raja."
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr "Valitse vapaa IP-osoite %s:sta"
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr "Aseta Istunnon Persistence"
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr "Ei tuettu vielä"
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr "lisää VIP"
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr "Luo VIP (virtuaalinen IP) tähän varantoon. Lisää nimi ja kuvaus VIP:lle. Määritä IP-osoite ja portti VIP:lle. Määritä protokollan ja istunnon persistence metodi VIP:lle Määritä maksimi sallittu määrä yhteyksiä. Admin Tila on päällä (ruksattu) oletuksena."
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr "Lisättiin Vip \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr "Ei voida lisätä VIP \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr "Vain yksi osoite voi olla määritettynä. Ei voida lisätä VIP %s."
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr "Ei voida hakea varantoa."
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr "Keksin nimi pitää olla määritettynä APP_COOKIE persistence"
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr "Jäsen(et)"
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr "Valitse jäsenet tähän varantoon"
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr "Paino"
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr "Valitse varanto"
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr "Ei voida hakea instanssilistausta"
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr "Ei palvelimia saatavilla. Paina Lisää lopettaaksesi. "
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr "Jäsentiedot"
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr "Lisää jäsen valittuun varantoon.\n\nValitse yksi tai useampi listatuista instansseista jotka lisätään varantoon jäseninä. Aseta numeerinen painoarvo tälle jäsenelle, määritä porttinumero tälle jäsenelle jossa hän toimii, esim 80."
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr "Lisättiin Jäsen \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr "Ei voida lisätä Jäsentä %s."
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr "Ei instansseja saatavilla. %s."
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr "Ei voida hakea porttilistausta."
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr "Viivtyä"
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr "Aikakatkaisu"
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr "Maksimi yritykset (1~10)"
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr "HTTP-metodi"
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr "URL"
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr "Odotetut HTTP-Status koodit"
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr "Valitse Tyyppi"
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr "Valitse HTTP-metodi"
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr "Monitorin Tiedot"
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr "Luo monitori varannolle.\n\nValitse kohdevaranto ja monitorin tyyppi. Määrittele viive, aikakatkaisu, raja uudelleenyrityksille jotka monitori vaatii. Määrittele metodi, URL-osoite ja HTTP-koodit joita odotetaan. "
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr "Lisättiin Monitori \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr "Ei voida lisätä monitoria \"%s\"."
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr "ID:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr "Asukkaan ID:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr "Varannon ID:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr "Osoite:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr "Protokollan Portti:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr "Paino:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr "Admin Tila Ylhäällä:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr "Tila:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr "Tyyppi:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr "Viive:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr "Aikakatkaisu:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr "Maksimi Yritykset:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr "HTTP-metodi:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr "URL-osoite:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr "Odotetut Koodit:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr "VIP ID:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr "Nimi:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr "Kuvaus:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr "Aliverkon ID:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr "Protokolla:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr "Kuormantasausmetodi:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr "Jäsenet:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr "Kunnossapito Monitorit:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr "Yhteyden Säntillisyys:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr "Keksin Nimi:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr "Avoimien yhteyksien raja:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr "Lisää Uusi Jäsen"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr "Lisää Uusi Monitori"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr "Lisää Uusi Varanto"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr "Määritä VIP:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr "Kuormantasaaja"
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr "Verkkotopologia"
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr "Tämä paneeli tarvitsee tuen javaskriptiltä. "
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr "Ei ole näytettäviä verkkoja, reitittimiä, tai yhdistettyjä instansseja joita näytetään."
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr "Lisää Aliverkko"
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr "Ei voida hakea verkon tietoja."
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr "Verkon Nimi. Tämä kenttä on valinnainen."
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr "Täältä voit luoda uuden verkon.\nLiitettävä aliverkko voidaan assosoida tähän verkkoon seuraavassa paneelissa."
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr "Aliverkon Nimi"
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr "Aliverkon nimi. Tämä kenttä on valinnainen."
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr "Verkon osoite"
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr "Verkon osoite on luokattoman verkon formaatissa (esim. 192.168.0.0/24)."
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr "Oletusyhdyskäytävän IP-osoite (valinnainen)"
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr "Oletusyhdyskäytävän osoite (esim. 192.168.0.254). Oletusarvo on ensimmäinen IP-osoite verkosta (esim. 192.168.0.1 verkosta 192.168.0.0/24). Jos käytät oletusarvoa, jätä kenttä tyhjäksi. Jos et halua oletusyhdyskäytävää, ruksaa alhaalta \"Poista käytöstä oletusyhdyskäytävä\" "
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr "Poista Käytöstä Oletusyhdyskäytävä"
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr "Voit luoda aliverkon joka on assosioitu uuteen verkkoon, jossa tapauksessa \"Verkon Osoite\" pitää määrittää. Jos haluat luoda verkon ILMAN aliverkkoa, poista valinta \"Luo Aliverkko\" valintaruudusta."
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr "Määritä \"Verkon Osoite\" tai tyhjennä \"Luo Aliverkko\" valintaruutu."
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr "Verkon Osoite ja IP-versio eivät täsmää."
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr "Aliverkon peite verkko-osoitteessa on liian pieni (/%s)."
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr "Oletusyhdyskäytävän IP ja IP-versio eivät täsmää."
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr "Määritä oletusyhdyskäytävän IP-osoite, tai ruksaa \"Poista käytöstä Oletusyhdyskäytävä\". "
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr "Aktivoi DHCP"
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr "Allokointi Varannot"
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr "IP-osoitteiden allokointivaranto. Jokainen kohde on &lt;ensimmäinen_ip_osoite&gt;,&lt;viimeinen_ip_osoite&gt; (e.g., 192.168.1.100,192.168.1.120) ja vain yksi kohde per rivi. "
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr "Nimipalvelimet"
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr "IP-lista aliverkon nimipalvelimista. Yksi kohde per rivi."
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr "Reitit"
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr "Määritellyt lisäreitit. Jokainen kohde on Each entry is &lt;luokaton_verkko&gt;,&lt;nexthop&gt; (e.g., 192.168.200.0/24,10.56.1.254) ja vain yksi kohde per rivi."
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr "Voit määrittää lisäatribuutteja aliverkolle."
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr "%(field_name)s: Väärä IP-osoite (value=%(ip)s)"
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr "%(field_name)s: Väärä IP-osoite (value=%(network)s)"
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr "Alku- ja loppuosoite pitää olla määritettynä (value=%s)"
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr "Alkuosoite on suurempi kuin loppuosoite (value=%s)"
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr "Väärä formaatti reitissä. Kohdeverkko ja nexthop pitää olla määritettyinä (value=%s)"
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr "Luotiin verkko \"%s\"."
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr "Ei voida luoda verkkoa \"%s\"."
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr "Verkko \"%s\" luotiin onnistuneesti."
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr "Epäonnistuttiin verkon luomisessa \"%(network)s\": %(reason)s"
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr "Aliverkko \"%s\" luotiin onnistuneesti."
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr "Ei voitu luoda aliverkkoa \"%(sub)s\" verkolle \"%(net)s\": %(reason)s"
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr "Tuhoa luotu verkko \"%s\", koska aliverkkoa ei voitu tehdä."
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr "Verkkoa \"%s\" ei voitu poistaa. "
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr "Liitetty"
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr "Irroitettu"
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr "Liitetty Laite"
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr "Ei voida hakea tarkempia tietoja portista."
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr "Ei voida hakea aliverkon tietoja."
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr "Ei voida hakea aliverkon tietoja"
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr "Voit luoda aliverkon liitettynä verkkoon. Lisäoptiot löytyvät \"Aliverkon Tiedot\" välilehdeltä. "
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr "Luotiin aliverkko \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr "Ei voida luoda aliverkkoa \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr "Oletusyhdyskäytävän osoite (esim. 192.168.0.254). Oletusarvo on ensimmäinen IP-osoite verkosta (esim. 192.168.0.1 verkosta 192.168.0.0/24). Jos käytät oletusarvoa, jätä kenttä tyhjäksi. Jos et halua oletusyhdyskäytävää, ruksaa alhaalta \"Poista käytöstä oletusyhdyskäytävä\" "
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr "Voit päivittää aliverkkoa joka on liitettynä verkkoon. Lisäoptiot löytyvät \"Aliverkon Tiedot\" välilehdeltä. "
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr "Päivitä"
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr "Päivitettiin aliverkko \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr "Ei voida päivittää aliverkkoa \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr "Aliverkko \"%s\" päivitettiin onnistuneesti."
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr "Ei voitu päivittää aliverkkoa \"%(sub)s\": %(reason)s"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr "Verkon Yleiskatsaus"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr "Palveluntarjoajan Verkko"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr "Verkon Tyyppi"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr "Fyysinen Verkko"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr "Segmentointi ID"
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr "Verkon tiedot:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr "Porttien yleiskatsaus"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr "Kiinteä IP."
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr "IP-osoitteet:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr "Aliverkon tunnus"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr "MAC-osoitteet"
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr "Portin Tiedot"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr "Aliverkon Yleiskatsaus"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr "IP-versio"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr "IP-osoitteiden allokointi varanto"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr "Aloita"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr "- Loppu"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr "DHCP päällä."
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr "Lisäreitit"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr "Kohde"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ": Next hop"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr "Tyhjä"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr "Nimipalvelin"
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr "Aliverkon Tiedot"
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr "Reititin"
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr "Ei voida poistaa reititintä \"%s\""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr "Tyhjä"
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr "Tyhjennetty"
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr "Oletusyhdyskäytävä"
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr "Oletusyhdyskäytävät"
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr "Ei voida poistaa oletusyhdyskäytävää reitittimeltä \"%(name)s\": \"%(msg)s\""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr "Ei voida hakea reitittimen tietoja."
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr "Ei voida hakea listausta ulkoisista verkoista \"%s\"."
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr "Ulkoista verkkoa \"%s\" ei löydy."
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr "Ei voida hakea tarkempia tietoja reitittimestä \"%s\"."
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr "Ei voida hakea ulkoista verkkoa \"%s\"."
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr "Reitittimen ID"
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr "Epäonnistuttiin verkkolistauksen hakemisessa %s"
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr "Valitse Aliverkko"
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr "Ei Aliverkkoja Saatavilla"
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr "Portti lisätty"
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr "Portin %s lisäämisessä epäonnistuttiin "
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr "Valitse Verkko"
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr "Ei verkkoja saatavilla."
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr "Oletusyhdyskäytävän portti lisättiin."
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr "Epäonnistuttiin oletusyhdyskäytävän asettamisessa %s"
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr "Portti"
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr "Portin %s poistamisessa epäonnistuttiin"
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr "Ei voida hakea reititintä. "
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr "Ei voida asettaa oletusyhdyskäytävää."
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr "Koko (GB)"
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr "Salaus"
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr "Käytä varmuusvedosta lähteenä"
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr "Verkkolevyn koko täytyy sama tai suurempi kuin varmuusvedoksen koko (%sGB)"
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr "Valittua varmuusvedosta ei voida ladata."
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr "Valitse varmuusvedos"
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr "Verkkolevyn koko ei voi olla pienempi kuin varmuusvedoksen koko (%sGB)"
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr "Verkkolevyä %(req)iGB ei voida luoda, koska sinulla on vain %(avail)iGB tilaa kiintiössä jälellä."
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr "Käytät jo kaikkia saatavilla olevia verkkolevyjä. "
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr "Verkkolevyä ei voida luoda."
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr "Liitä Instanssiin"
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr "Valitse instanssi johonka liitetään."
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr "Tunnistamaton instanssi (None)"
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr "Liitetään verkkolevy %(vol)s instanssiin %(inst)s kohteeseen %(dev)s."
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr "Ei voida liittää levykuvaa."
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr "Luodaan verkkolevyn varmuusvedosta \"%s\""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr "Ei voida luoda verkkolevyn varmuusvedosta."
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr "Ei voida poistaa verkkolevyä \"%s. Yksi tai useampi varmuusvedos on riippuvainen siitä. "
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr "Muokkaa Liitoksia"
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr "%sGB"
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr "Ei voida hakea liitoksien tietoja."
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr "Liitetty instanssin %(instance)s kohteeseen %(dev)s "
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr "Irroita"
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr "Irroitetaan"
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr "%(dev)s liitettynä instanssiin %(instance_name)s"
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr "Ei voida hakea verkkolevyn tietoja."
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr "Ei voida hakea verkkolevylistausta."
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr "Ei voida hakea verkkolevy/insanssi liittämistietoja"
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr "Ei voida hakea verkkolevyn tietoja."
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr "Hallitse Verkkolevyjen Liittämisiä"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr "Liitä Instanssiin"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr "Liitä Verkkolevy"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr "Verkkolevyt ovat \"block devices?\" jotka voidaan liittää instanssiin."
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr "Verkkolevyjen Kiintiöt"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr "Gigatavut Yhteensä"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr "Verkkolevyjen Määrä"
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr "Luo Verkkolevyn Varmuusvedos"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr "Verkkolevyn Yleiskatsaus"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr "Liitokset"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr "Ei liitetty"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr "Metadata"
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr "Luo Verkkolevy"
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr "Luo verkkolevyn Varmuusvedos"
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr "Asetukset"
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr "Asetukset Tallennettu."
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr "Käyttäjän Asetukset"
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr "Täältä voit muokata käyttöliittymän asetuksia käyttäjille."
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Kielletty"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Koti"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Sivua ei löydy"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "Haluttu sivu ei ole olemassa"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "Sivusto on muuttanut, tai osoite on väärin muodostettu"
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr "Server Error"
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr "Jotain meni mönkään."
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr "Tuntematon virhe. Yritä päivittää sivu. Jos tämä ei auta, ota yhteyttä paikalliseen ylläpitäjään."
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr "Apua"
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Kirjauduttu sisään käyttäjänä"
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr "Kirjaudu Ulos"
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr "Salasanan täytyy olla 8 - 18 merkkiä pitkä."
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr "Ei voida hakea käyttötietoja."
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr "Katsot dataa tulevaisuudesta, joka suattaapi olla, tai olla olematta. "
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr "Lataa CSV-katsaus."
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr "VCPU Tunnit"
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr "Projektin nimi"
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr "Levy GB Tunnit"
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr "Käyttökatsaus"
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr "Uptime"
diff --git a/openstack_dashboard/locale/fr/LC_MESSAGES/django.mo b/openstack_dashboard/locale/fr/LC_MESSAGES/django.mo
deleted file mode 100644
index 7c6f419c..00000000
--- a/openstack_dashboard/locale/fr/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/fr/LC_MESSAGES/django.po b/openstack_dashboard/locale/fr/LC_MESSAGES/django.po
deleted file mode 100644
index 1a44db0a..00000000
--- a/openstack_dashboard/locale/fr/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4710 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# alexis.monville <alexis.monville@ayeba.fr>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: fr\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "Bulgare"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "Tchèque"
-
-#: settings.py:154
-msgid "English"
-msgstr "Anglais"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Espagnol"
-
-#: settings.py:156
-msgid "French"
-msgstr "Français"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Italien"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Japonais"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "Coréen"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "Néerlandais"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Polonais"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Portugais"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "Portugais"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Chinois simplifié"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Chinois traditionnel"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr ""
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "Admin"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "Nom"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr "VCPUs"
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr "RAM Mo"
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "RAM"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr ""
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr ""
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr ""
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr ""
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr ""
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr ""
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr ""
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr ""
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Projets"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr ""
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr ""
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr ""
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr ""
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr ""
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Interdit"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Accueil"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Page non trouvée"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "La page que vous recherchée n'existe pas"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "Vous avez peut-être mal orthographié l'adresse ou la page a été déplacée"
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr ""
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/hu/LC_MESSAGES/django.mo b/openstack_dashboard/locale/hu/LC_MESSAGES/django.mo
deleted file mode 100644
index 7a6d22ff..00000000
--- a/openstack_dashboard/locale/hu/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/hu/LC_MESSAGES/django.po b/openstack_dashboard/locale/hu/LC_MESSAGES/django.po
deleted file mode 100644
index ff8f9468..00000000
--- a/openstack_dashboard/locale/hu/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4711 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2012
-# Gabor Kelemen <kelemeng at gnome dot hu>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: hu\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "Bolgár (Bulgária)"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "Cseh"
-
-#: settings.py:154
-msgid "English"
-msgstr "Angol"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Spanyol"
-
-#: settings.py:156
-msgid "French"
-msgstr "Francia"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Olasz"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Japán"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "Koreai (Korea)"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "Holland (Hollandia)"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Lengyel"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Portugál"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "Portugál (Brazília)"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Kínai (egyszerűsített)"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Kínai (hagyományos)"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr "Ismeretlen példány"
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr "%(type)s (%(backend)s háttérprogram)"
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr "ENGEDÉLYEZÉS: %(from)s:%(to)s innen: %(group)s"
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr "ENGEDÉLYEZÉS: %(from)s:%(to)s innen: %(cidr)s"
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr "Rendszer panel"
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "Admin"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "Név"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr "VCPU-k"
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr "RAM MB"
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr "Gyökér lemez GB"
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr "Ideiglenes lemez GB"
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr "„%s” változat létrehozva."
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr "Nem lehet létrehozni a változatot."
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr "„%s” változat frissítve."
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr "Nem lehet frissíteni a változatot."
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr "Változatok"
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr "Változat"
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr "Változat létrehozása"
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr "Változat szerkesztése"
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr "%sMB"
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr "Változat neve"
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "RAM"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr "Gyökér lemez"
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr "Ideiglenes lemez"
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr "Nem lehet lekérni a változat listát."
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr "Nem lehet lekérni a változat adatokat."
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr "Létrehozás"
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr "Szerkesztés"
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "Leírás"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr "Innen tudja meghatározni az új változat méretét."
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "Mégse"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr "Innen tudja módosítani a jelenlegi változat méretét."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr "Megjegyzés: ez nem befolyásolja a változatot használó meglévő példányokhoz lefoglalt erőforrásokat."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr "Mentés"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "Képek"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr "Kép neve"
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr "Nem lehet lekérni a képlistát."
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr "Kép létrehozása"
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr "Leírás:"
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr "Adja meg a képszolgáltatásba feltöltendő képet."
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr "Jelenleg csak HTTP URL-en elérhető lemezképek támogatottak. A lemezkép helyének elérhetőnek kell lennie a lemezkép szolgáltatás által. A tömörített lemezkép-binárisok támogatottak (.zip és .tar.gz.)"
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr "Ne feledje: "
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr "A Lemezkép helye mezőnek a lemezkép binárisra mutató érvényes és közvetlen URL-címnek kell lennie. Az átirányító vagy hibaoldalakat kiszolgáló URL-ek használhatatlan lemezképeket eredményeznek."
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr "Kép létrehozása"
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr "Kép frissítése"
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr "Innen tudja módosítani a kép különböző tulajdonságait."
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr "Kvóta neve"
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr "Határ"
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr "Kvóták"
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr "Azonosító"
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr "Szolgáltatás"
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr "Gép"
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr "Engedélyezve"
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr "Szolgáltatások"
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr "Alapértelmezett kvóták"
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr "Nem lehet lekérni a kvótainformációt."
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "Példányok"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr "Példány"
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "Projekt"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr "IP-cím"
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr "Méret"
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr "Állapot"
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr "Feladat"
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr "Bekapcsolási állapot"
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr "Nem lehet lekérni a példány listát."
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr "Nem kérhetők le a példány bérlőinformációi."
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr "Nem lehet lekérni a példány méret információit."
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr "Minden példány"
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr "Admin állapot"
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr "Megosztott"
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr "Projekt kiválasztása"
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr "A hálózat (%s) sikeresen létrehozva."
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr "A hálózat (%s) létrehozása nem sikerült."
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr "Azonosító"
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr "A hálózat (%s) sikeresen frissítve."
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr "A hálózat (%s) frissítése nem sikerült."
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "Hálózatok"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr "Hálózat"
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr "A hálózat (%s) törlése nem sikerült."
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr "Hálózat létrehozása"
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr "Hálózat szerkesztése"
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "Hálózat neve"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr "Társított alhálózatok"
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr "A hálózat lista nem kérhető le."
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr "Az alhálózat lista nem kérhető le."
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr "A port lista nem kérhető le."
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr "Nem lehet lekérni a(z) „%s” hálózat részleteit."
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "Hálózatazonosító"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr "Eszközazonosító"
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr "A port (%s) sikeresen létrehozva."
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr "Nem sikerült a port létrehozása a(z) %s hálózathoz."
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr "A port (%s) sikeresen frissítve."
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr "Nem sikerült a port (%s) frissítése."
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "Port"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "Portok"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr "Nem sikerült az alhálózat (%s) törlése."
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr "Port létrehozása"
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr "Port szerkesztése"
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr "Fix IP-k"
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr "Csatlakoztatott eszköz"
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr "Áttekintés"
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr "Nem lehet lekérni a port részleteit."
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr "Nem lehet lekérni a hálózatot."
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr "Alhálózat"
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr "Alhálózatok"
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr "Alhálózat létrehozása"
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr "Alhálózat szerkesztése"
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr "CIDR"
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr "IP verzió"
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr "Átjáró IP"
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr "Nem kérhető le a(z) %s hálózat egy alhálózathoz"
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr "Válasszon egy nevet a hálózatához."
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr "Itt frissítheti a hálózat szerkeszthető tulajdonságait."
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr "Változtatások mentése"
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr "Hálózat frissítése"
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr "Létrehozhat egy portot a hálózatnak. Ha megadja egy csatolandó eszköz azonosítóját, akkor a megadott eszköz csatolásra kerül a létrehozott porthoz."
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr "Itt frissítheti a port szerkeszthető tulajdonságait."
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr "Port frissítése"
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr "Hálózat részletei"
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr "Alhálózat frissítése"
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr "Használat áttekintése"
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr "Monitorozás"
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Projektek"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr "Felhasználók módosítása"
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr "Használat megtekintése"
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr "Projekt létrehozása"
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr "Projekt szerkesztése"
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr "Projektazonosító"
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr "Eltávolítás"
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr "Eltávolítva"
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr "Felhasználó"
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr "Felhasználók"
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr "Nem lehet lekérni a szerep információkat."
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr "Szerepek"
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr "A projekt felhasználói"
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr "Hozzáadás a projekthez"
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr "Új felhasználók hozzáadása"
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr "Nem lehet lekérni a projekt információkat."
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr "Nem lehet lekérni a projekt listát."
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr "Nem lehet lekérni a felhasználókat."
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr "Nem kérhetők le az alapértelmezett kvótaértékek."
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr "Nem kérhetők le a projekt részletei."
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr "Beszúrt fájl tartalom bájtok"
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr "Metaadat elemek"
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr "Beszúrt fájlok"
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr "Kötetek"
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr "Gigabájt"
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr "RAM (MB)"
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr "Lebegő IP-k"
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr "Biztonsági csoportok"
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr "Biztonsági csoport szabályok"
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr "Kvóta"
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr "Innen tudja beállítani a projekt kvótáit (maximum korlátjait)."
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr "Projektinformáció"
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr "Innen tud létrehozni új projektet a felhasználók szervezéséhez."
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr "Nem lehet lekérni a felhasználó listát. Kérjük próbálja meg később."
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr "A projekt tagjai"
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr "Minden felhasználó"
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr "Nem található felhasználó."
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr "Nem lehet lekérni a felhasználó listát."
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr "Új projekt létrehozva: „%s”."
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr "Nem lehet létrehozni a projektet: „%s”."
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr "Nem sikerült hozzáadni %s projekt tagjait és beállítani a projekt kvótáit."
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr "Nem lehet beállítani a projekt kvótákat."
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr "Innen tudja szerkeszteni a projekt részleteit."
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr "„%s” projekt módosítva."
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr "Nem lehet módosítani a(z) „%s” projektet."
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr "Nem sikerült módosítani %s projekt tagjait és frissíteni a projektkvótákat."
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr "A projektinformációk és -tagok módosítva, de a projektkvóták nem módosíthatók."
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr "Felhasználó hozzáadása a projekthez"
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr "A felhasználói szerep kiválasztása a projekthez."
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr "Hozzáadás"
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr "Felhasználó létrehozása a projekthez: „%(tenant_name)s”."
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr "Innen létre tud hozni új felhasználót, akit hozzáadhat ehhez a projekthez."
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr "Felhasználó létrehozása"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr "Kvóta frissítése"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr "Innen tudja szerkeszteni a projekt %(tenant.name)s kvótáit (maximális korlátjait)."
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr "Projekt frissítése"
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr "Innen tudja szerkeszteni a projektet."
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr "Itt tagokat vehet fel a projektbe az összes elérhető felhasználó listájából, vagy eltávolíthatja azokat."
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr "Új felhasználó hozzáadása"
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr "Projekt használat áttekintése"
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr "Projekt használat"
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr "A projekt felhasználói"
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr "Típus"
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr "A jelszavak nem egyeznek."
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr "Felhasználónév"
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr "E-mail"
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr "Jelszó"
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr "Jelszó megerősítése"
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr "Elsődleges projekt"
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr "Szerep"
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr "„%s” felhasználó sikeresen létrehozva."
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr "A felhasználó nem adható az elsődleges projekthez."
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr "Nem hozható létre felhasználó."
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr "név"
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr "e-mail"
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr "elsődleges projekt"
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr "A(z) %s felhasználóhoz nincs szerep megadva"
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr "jelszó"
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr "A felhasználó sikeresen frissítve."
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr "Nem lehet frissíteni a felhasználó %(attributes)s jellemzőit."
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr "Engedélyezés"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr "Letiltás"
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr "Letiltva"
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr "Nem tilthatja le azt a felhasználót, amellyel jelenleg be van jelentkezve."
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr "Felhasználói azonosító"
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr "A felhasználó nem frissíthető."
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr "A felhasználói szerepek nem kérhetők le."
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr "Itt létrehozhat új felhasználókat, és projekthez rendelheti azokat."
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr "Felhasználó frissítése"
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr "Itt szerkesztheti a felhasználók adatait, beleértve az alapértelmezett projektjeiket."
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr "Kötet részletei"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr "Kötet részletei"
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr "Compute kezelése"
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr "Objektumtár"
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr "Hozzáférés és biztonság"
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr "Nem kérhetők le a biztonsági csoportok."
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr "Kulcspárok"
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr "Nem kérhető le a kulcspárlista."
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr "Nem kérhetők le a lebegő IP-címek."
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr "A lebegő IP-k tárai nem kérhetők le."
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr "EC2 hitelesítési adatok letöltése"
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr "OpenStack RC fájl letöltése"
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr "Szolgáltatás végpontja"
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr "API végpontjai"
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr "Nem lehet lekérni az EC2 hitelesítési adatait."
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr "Hiba a zip fájl írásakor: %(exc)s"
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr "Hiba az RC fájl letöltésekor: %s"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr "Tároló"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr "Lebegő IP lefoglalva: %(ip)s."
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr "Nem foglalható le lebegő IP."
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr "IP lefoglalása projekthez"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr "Elengedés"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr "Elengedve"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr "Lebegő IP"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr "Lebegő IP társítása"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr "Lebegő IP társításának megszüntetése"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr "Lebegő IP társítása sikeresen megszüntetve: %s"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr "Lebegő IP társítása nem szüntethető meg."
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr "Lebegő IP-k tára"
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr "A lebegő IP-k tárai nem érhetők el."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr "Válassza ki a kijelölt példányhoz társítani kívánt IP-címet."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr "Válasszon IP-címet"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr "Nem érhetők el IP-címek"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr "Válasszon egy példányt"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr "Nem érhetők el példányok"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr "Lebegő IP társítások kezelése"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr "Társítás"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr "%s IP-cím társítva."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr "Nem lehet társítani a(z) %s IP-címet."
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr "Kulcspár neve"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr "A kulcspárnevek csak betűket, számokat, aláhúzásokat és kötőjeleket tartalmazhatnak."
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr "Nyilvános kulcs"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr "A nyilvános kulcs sikeresen importálva: %s"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr "A kulcspár nem importálható."
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr "Kulcspár"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr "Kulcspár importálása"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr "Kulcspár létrehozása"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr "Ujjlenyomat"
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr "Nem hozható létre kulcspár: %(exc)s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr "A biztonsági csoport sikeresen létrehozva: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr "Nem hozható létre biztonsági csoport."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr "IP protokoll"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr "Szabály alkalmazása ezen protokollra."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr "Küldő port"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr "Cél port"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr "Kód"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr "Forrás"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr "Biztonsági csoport"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr "Osztály nélküli tartományközi útválasztás (például 192.168.0.0/24)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr "Az ICMP típus érvénytelen."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr "Az ICMP kód érvénytelen."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr "Az ICMP típus nincs a (-1, 255) tartományban"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr "Az ICMP kód nincs a (-1, 255) tartományban"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr "A „forrás” portszám érvénytelen."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr "A „cél” portszám érvénytelen."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr "A „cél” portszám nem lehet kisebb a „forrás” portszámnál."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr "Szabály sikeresen hozzáadva: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr "Nem vehető fel szabály a biztonsági csoporthoz."
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr "Biztonsági csoport létrehozása"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr "Szabályok szerkesztése"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr "Szabály hozzáadása"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr "Szabály"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr "Szabályok"
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr "Nem lehet lekérni a biztonsági csoportot."
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr "%s (jelenlegi)"
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr "Hozzáférés és biztonság"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr "Lebegő IP lefoglalása"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr "Lebegő IP lefoglalása a megadott lebegő IP tárból."
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr "Projekt kvóták"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr "IP lefoglalása"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr "A kulcspárok SSH hitelesítési adatok, amelyek beszúrásra kerülnek a lemezképekbe azok indításakor. Az új kulcspár létrehozása regisztrálja a nyilvános kulcsot, és letölti a magánkulcsot (egy .pem fájlt)."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr "A kulcsot úgy védje és használja, mintha egy normál SSH magánkulcs lenne."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr "Kulcspár letöltése"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr "A kulcspár (&quot;%(keypair_name)s&quot;) letöltése automatikusan indul. Ha mégsem, használja a lenti hivatkozást."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr "Kulcspár (&quot;%(keypair_name)s&quot;) letöltése"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr "Innen hozhat létre új biztonsági csoportot"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr "Biztonsági csoport szabályok szerkesztése"
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr "Swift"
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr "Konténer"
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr "A perjel nem elfogadott karakter."
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr "Konténer neve"
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr "A konténer sikeresen létrehozva."
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr "A mappa sikeresen létrehozva."
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr "Nem lehet létrehozni a konténert."
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr "Objektum neve"
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr "Fájl"
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr "Az objektum sikeresen feltöltve."
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr "Nem lehet feltölteni az objektumot."
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr "Cél konténer"
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr "Cél objektum neve"
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr "„%(orig)s” átmásolva ide: „%(dest)s” mint „%(new)s”."
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr "Nem lehet másolni az objektumot."
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr "Konténerek"
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr "Konténer létrehozása"
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr "Konténer megtekintése"
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr "Objektum feltöltése"
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr "Objektum"
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr "Objektumok"
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr "Másolás"
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr "Letöltés"
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr "Nem lehet lekérni a konténer listát."
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr "Nem lehet lekérni az objektum listát."
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr "Nem lehet lekérni az objektumot."
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr "Nem lehet listázni a konténereket."
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr "Objektum másolása"
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr "Új másolat létrehozása meglévő objektumról az itt vagy másik konténerben való tároláshoz. Megadhatja azt az útvonalat is, ahol az új másolatnak élnie kell a kiválasztott konténerben."
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr "A konténer az adatait tároló egység, amely lehetővé teszi adatai rendszerezését. A konténert úgy képzelheti el, mint egy mappát Windows alatt vagy könyvtárat Unix alatt. Az alapvető különbség a konténer és más fájlrendszerbeli fogalmak között az, hogy a konténerek nem ágyazhatók egymásba. Azonban végtelen számú konténert hozhat létre a fiókjában. Az adatokat konténerekben kell tárolni, így legalább egy konténert definiálni kell a fiókjában az adatok feltöltése előtt."
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr "Objektum feltöltése a konténerbe"
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr "Objektumok feltöltése"
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr "Képek és pillanatképek"
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr "Nem lehet lekérni a képeket."
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr "Nem lehet lekérni a pillanatképeket."
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr "Nem lehet lekérni a kötet pillanatképeket."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr "Kép helye"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr "Egy külső (HTTP) URL a képek betöltéséhez."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr "Formátum"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr "AKI - Amazon Kernel Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr "AMI - Amazon Machine Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr "ARI - Amazon Ramdisk Image"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr "ISO - Optikai lemezkép"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr "QCOW2 - QEMU Emulátor"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr "Minimum lemez (GB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr "A kép indításához szükséges minimális lemezméret. Ha nincs megadva, az alapértelmezett értéke 0 (nincs minimum)."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr "Minimum RAM (MB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr "Nyilvános"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr "A(z) %s lemezkép létrehozásra sorba állítva."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr "Nem lehet létrehozni új képet."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr "Kernel azonosító"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr "RAM-lemez azonosító"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr "Architektúra"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr "Nem lehet feltölteni a képet: „%s”."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr "A kép sikeresen feltöltve."
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr "Indítás"
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr "Kép"
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr "Nem lehet lekérni a kép részleteit."
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr "Nem lehet lekérni a képet."
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr "Példány azonosító"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr "Pillanatkép neve"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr "Pillanatkép („%(name)s”) létrehozva ehhez a példányhoz: „%(inst)s”"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr "Nem lehet pillanatképet létrehozni."
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr "Pillanatkép"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr "Pillanatképek"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr "Példány pillanatképek"
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr "Nem lehet lekérni a példányt."
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr "Képek és pillanatképek"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr "Kép áttekintése"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr "Információ"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr "Ellenőrzőösszeg"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr "Létrehozva"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr "Frissítve"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr "Specifikációk"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr "Konténerformátum"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr "Lemezformátum"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr "Egyéni tulajdonságok"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr "Euca2ools állapot"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr "Képtípus"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr "Kép részletek "
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr "Pillanatkép létrehozása"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr "A pillanatképek megőrzik a futó példány lemezállapotát."
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr "Kötet"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr "GB"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr "Pillanatkép létrehozása"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr "Kötet pillanatképének részletei"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr "Kötet pillanatképének részletei"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr "Kötet pillanatképe"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr "Kötet pillanatképei"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr "Kötet létrehozása"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr "Kötet neve"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr "Nem lehet lekérni a pillanatkép részleteit."
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr "Bezárás"
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr "Ütemezett bezárás"
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr "Szüneteltetés"
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr "Folytatás"
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr "Szüneteltetve"
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr "Folytatva"
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr "Felfüggesztés"
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr "Felfüggesztve"
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr "Példány indítása"
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr "Példány szerkesztése"
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr "Napló megtekintése"
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s lemez"
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr "Nem érhető el"
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr "Példány neve"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr "Napló"
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr "Nem lehet letölteni a példány („%s”) naplóját."
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr "Nem lehet lekérni a példányokat."
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr "Nem lehet megszerezni a példány („%s”) VNC konzolját."
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr "Nem lehet lekérni a példány részleteit."
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr "Nem lehet lekérni a(z) „%s” példány részleteit."
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr "Újratöltés"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr "Példány konzol napló"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr "Napló hossza"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr "Ugrás"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr "Teljes napló megtekintése"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr "Példány áttekintése"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr "VCPU"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr "Lemez"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr "IP-címek"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr "Nincsenek szabályok megadva."
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr "Meta"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr "Kulcsnév"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr "Csatolt kötetek"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr "Csatolva ehhez"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr "ezen:"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr "Nincsenek csatolt kötetek."
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr "A példányt személyre szabhatja az elindítása után az itt elérhető beállításokkal."
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr "A „Testre szabó szkript” mező megfelel a más rendszereken használt „Felhasználói adatoknak”."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr "Adja meg a részleteket egy példány indításához."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr "Az alábbi diagram megjeleníti a projekt által használt erőforrásokat a projekt kvótáihoz viszonyítva."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr "Változat részletei"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr "Lemez összesen"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr "MB"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr "Példányok száma"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr "VCPU-k száma"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr "Teljes RAM"
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr "Egy példány különféle típusú csatolt tárolókkal indítható el. Itt választhat ezekből."
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr "Példány részletei"
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr "Projekt és felhasználó"
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr "Ne induljon a kötetről."
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr "Indulás a kötetről."
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr "Indítás a kötet pillanatképről (létrehoz egy új kötetet)."
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr "Kötet beállítások"
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr "Eszköz neve"
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr "Kötet csatolási pontja (például „vda” csatolása a „/dev/vda” helyre)."
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr "Törlés bezáráskor"
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr "Kötet törlése a példány bezárásakor"
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr "Kérjük válasszon egy kötetet vagy ezt: %s."
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr "Kötet kiválasztása"
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr "Nem lehet lekérni a kötetek listáját."
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr "Kötet pillanatkép kiválasztása"
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr "Nem lehet lekérni a kötet pillanatképek listáját."
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr "Példány forrása"
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr "Példány pillanatképe"
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr "Az indítandó kép mérete."
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr "Példányok száma"
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr "Az indítandó példányok száma"
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr "Részletek"
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr "Nincsenek elérhető kép források; először létre kell hoznia egy képet, mielőtt megpróbál indítani egy példányt."
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr "Válasszon beállítást a példányforráshoz."
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr "Több példány indítása csak lemezképek és példánypillanatképek esetén támogatott."
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr "Nem lehet lekérni a nyilvános képeket."
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr "Nem lehet lekérni képeket a jelenlegi projekthez."
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr "Kép kiválasztása"
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr "Nincsenek elérhető képek."
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr "Példány pillanatkép kiválasztása"
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr "Nincsenek elérhető pillanatképek."
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr "Nem lehet lekérni a példány változatokat."
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr "Nem lehet lekérni a kvóta információkat."
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr "Melyik kulcspárt használja a hitelesítéshez."
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr "Példány indítása ezekben a biztonsági csoportokban."
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr "Hozzáférés vezérlése a példányhoz kulcspárok, biztonsági csoportok és egyéb mechanizmusok használatával."
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr "Nem lehet lekérni a kulcspárokat."
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr "Kulcspár kiválasztása"
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr "Nem érhetők el kulcspárok."
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr "Nem lehet lekérni a biztonsági csoportok listáját"
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr "Testre szabó szkript"
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr "A példány létrejötte után futtatandó szkript vagy parancsok halmaza (maximum 16 KB)."
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr "Létrehozás után"
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr "Példány indítása ezekkel a hálózatokkal"
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr "Hálózatkezelés"
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr "Hálózatok kiválasztása a példányához."
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr "Nem lehet lekérni a hálózatokat."
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr "%(count)s „%(name)s” nevű elindítva."
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr "Nem indítható el %(count)s „%(name)s”."
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr "%s példányok"
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr "példány"
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr "Alhálózat hozzáadása"
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr "A hálózat részletei nem kérhetők le."
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr "Itt létrehozhat egy új hálózatot.\nEzen kívül a következő panelen létrehozható a hálózathoz társított alhálózat."
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr "Hálózati cím"
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr "Hálózati cím CIDR formátumban (például 192.168.0.0/24)"
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr "Átjáró IP (elhagyható)"
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr "Létrehozhat az új hálózathoz társítva egy alhálózatot, ebben az esetben meg kell adni a „Hálózati címet”. Ha a hálózatot alhálózat NÉLKÜL szeretné létrehozni, akkor törölje az „Alhálózat létrehozása” négyzetet."
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr "Adja meg a „Hálózati címet”, vagy törölje az „Alhálózat létrehozása” négyzetet."
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr "A hálózati cím és az IP verzió nem konzisztensek."
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr "Az átjáró IP-címe és az IP verzió nem konzisztensek."
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr "„%s” hálózat létrehozva."
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr "Nem hozható létre a hálózat („%s”)."
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr "A hálózat („%s”) sikeresen létrejött."
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr "Az alhálózat („%s”) sikeresen létrejött."
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr "Csatolva"
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr "Leválasztva"
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr "Nem lehet lekérni a port részleteit"
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr "Az alhálózat részletei nem kérhetők le."
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr "Nem lehet lekérni az alhálózat részleteit"
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr "Hálózat áttekintése"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr "Hálózat részletei: "
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr "Portáttekintés"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr "Fix IP"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr "IP-cím:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr "Alhálózati azonosító"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr "MAC cím"
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr "Port részletei"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr "Alhálózat áttekintése"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr "IP verzió"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr "IP-foglalási tár"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr "Kezdet"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr " - Vég"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr "Alhálózat részletei"
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr "Méret (GB)"
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr "Pillanatkép használata forrásként"
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr "A kötet méretének legalább a pillanatkép méretét el kell érnie (%s GB)"
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr "Nem tölthető be a megadott pillanatkép."
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr "Válasszon pillanatképet"
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr "A kötet mérete nem lehet kisebb a pillanatkép méreténél (%s GB)"
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr "Nem hozható létre %(req)i GB méretű kötet, mivel csak %(avail)i GB érhető el a kvótából."
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr "Már minden rendelkezésre álló kötet használatban van."
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr "Nem hozható létre kötet."
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr "Példányhoz csatolás"
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr "Válasszon példányt a csatoláshoz."
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr "Ismeretlen példány (nincs)"
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr "%(vol)s kötet csatolása a(z) %(inst)s példányhoz ezen: %(dev)s."
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr "A kötet nem csatolható."
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr "Kötetpillanatkép („%s”) létrehozása"
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr "Nem hozható létre kötetpillanatkép."
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr "Nem törölhető a kötet („%s”). Legalább egy pillanatkép függ tőle."
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr "Csatolások szerkesztése"
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr "%s GB"
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr "A csatolási információk nem kérhetők le."
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr "Csatolva %(instance)s példányhoz ezen: %(dev)s"
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr "Leválasztás"
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr "Leválasztás"
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr "%(dev)s ezen példányon: %(instance_name)s"
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr "A kötet részletei nem kérhetők le."
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr "A kötetlista nem kérhető le."
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr "A kötet- vagy példánycsatolási információk nem kérhetők le."
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr "A kötetinformációk nem kérhetők le."
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr "Kötetcsatolások kezelése"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr "Csatolás példányhoz"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr "Kötet csatolása"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr "A kötetek példányokhoz csatolható blokkos eszközök."
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr "Kötetkvóták"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr "Gigabájtok összesen"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr "Kötetek száma"
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr "Kötet pillanatkép létrehozása"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr "Kötet áttekintése"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr "Csatolások"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr "Nem csatolt"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr "Kötet létrehozása"
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr "Kötet pillanatkép létrehozása"
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr "Beállítások"
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr "Beállítások elmentve."
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr "Felhasználói beállítások"
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr "Innen tudja módosítani a felhasználója vezérlőpultjának beállításait."
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Tiltott"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Kezdőlap"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Az oldal nem található"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "A keresett oldal nem létezik"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "Elgépelhette a címet, vagy az oldalt áthelyezték."
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr "Súgó"
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "Belépve mint"
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr "Kijelentkezés"
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr "A jelszónak 8 és 18 karakter közöttinek kell lennie."
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr "Nem lehet lekérni a használati információkat."
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr "Olyan jövőbeli adatokat néz, amelyeknek a létezése nem garantált."
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr "CSV összegzés letöltése"
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr "VCPU órák"
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr "Projekt neve"
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr "Lemez GB órák"
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr "Használati összegzés"
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr "Futási idő"
diff --git a/openstack_dashboard/locale/it/LC_MESSAGES/django.mo b/openstack_dashboard/locale/it/LC_MESSAGES/django.mo
deleted file mode 100644
index b184c418..00000000
--- a/openstack_dashboard/locale/it/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/it/LC_MESSAGES/django.po b/openstack_dashboard/locale/it/LC_MESSAGES/django.po
deleted file mode 100644
index 7bf033fe..00000000
--- a/openstack_dashboard/locale/it/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4885 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr ""
-
-#: settings.py:153
-msgid "Czech"
-msgstr ""
-
-#: settings.py:154
-msgid "English"
-msgstr ""
-
-#: settings.py:155
-msgid "Spanish"
-msgstr ""
-
-#: settings.py:156
-msgid "French"
-msgstr ""
-
-#: settings.py:157
-msgid "Italiano"
-msgstr ""
-
-#: settings.py:158
-msgid "Japanese"
-msgstr ""
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr ""
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr ""
-
-#: settings.py:161
-msgid "Polish"
-msgstr ""
-
-#: settings.py:162
-#, fuzzy
-msgid "Portuguese"
-msgstr "Porte"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr ""
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr ""
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr ""
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr "Istanza sconosciuta"
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr "Panello di sistema"
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "Amministratore"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "Nome"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr "Disco principale in GB"
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-#, fuzzy
-msgid "Unable to get flavor list"
-msgstr "Impossible recuperare lista utenti"
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr "Flavor"
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:60
-#, fuzzy
-msgid "Swap Disk"
-msgstr "Totale disco"
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-#, fuzzy
-msgid "Key"
-msgstr "Keypair"
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, fuzzy, python-format
-msgid "Created extra spec \"%s\"."
-msgstr "Rete \"%s\" creata."
-
-#: dashboards/admin/flavors/extras/forms.py:48
-#, fuzzy
-msgid "Unable to create flavor extra spec."
-msgstr "Impossibile creare il container"
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, fuzzy, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr "Rete \"%s\" creata."
-
-#: dashboards/admin/flavors/extras/forms.py:66
-#, fuzzy
-msgid "Unable to edit extra spec."
-msgstr "Impossible creare utente"
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-#, fuzzy
-msgid "ExtraSpecs"
-msgstr "Specifiche"
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr "Crea"
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr "Modifica"
-
-#: dashboards/admin/flavors/extras/tables.py:66
-#, fuzzy
-msgid "Extra Specs"
-msgstr "Specifiche"
-
-#: dashboards/admin/flavors/extras/views.py:61
-#, fuzzy
-msgid "Unable to retrieve extra spec list."
-msgstr "Impossible recuperare lista utenti"
-
-#: dashboards/admin/flavors/extras/views.py:90
-#, fuzzy
-msgid "Unable to retrieve flavor extra spec data."
-msgstr "Impossible recuperare informazioni sulle porte"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "Descrizione"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "Annulla"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances "
-"using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr "Salva"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "Immagini"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr "Nome Immagine"
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr "Impossible recuperare lista immagini"
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr "Crea un'immagine"
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr "Descrizione:"
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr "Specifica un immagine da caricare su servizio Immagini"
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-"Al momento sono supportate esclusivamente immagini accessibili attraverso un "
-"indirizzo HTTP. L'indirizzo dell'immagine deve essere accessible dal "
-"servizio Immagini. Immagini compresse (.zip e .tar.gz) sono supportate."
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr "Per favore, osserva:"
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-#, fuzzy
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary. "
-"URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-"Il campo per l'indirizzo dell'immagine DEVE essere un URL valido e diretto "
-"per il file binario contenente l'immagine. L'utilizzo di URLs che effettuano "
-"un redirect o restituiscono pagine di errore comporterà l'inutilizzabilità "
-"dell'immagine."
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr "Crea immagine"
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr "Aggiorna immagini"
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-#, fuzzy
-msgid "System Info"
-msgstr "Panello di sistema"
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr "Abilitato"
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "Istanze"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr "Istanza"
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "Progetto"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr "Indirizzo IP"
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr "Dimensione"
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr "Stato"
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr "Stato alimentazione"
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr "Impossible recuperare la lista delle istanze"
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr "Impossible recuperare informazioni tenant"
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr "Impossibile recuperare informazioni sulle dimensioni dell'istanza"
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-#, fuzzy
-msgid "External Network"
-msgstr "Aggiorna rete"
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr "La rete %s è stata aggiornata correttamente."
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr ""
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "Reti"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "Nome della rete"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr ""
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "ID della rete"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr "ID dispositivo"
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-#, fuzzy
-msgid "Device Owner"
-msgstr "ID dispositivo"
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "Porta"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "Porte"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr "Eliminazione della sottorete %s fallita"
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr "Indirizzo IP fisso"
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr "Sommario"
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr "Impossible recuperare informazioni sulle porte"
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr "Impossible recuperare rete."
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr "Sottorete"
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr "Sottoreti"
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr "Modifica sottorete"
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr "CIDR"
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr "Versione protocollo IP"
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr "Indirizzo IP del Gateway"
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr "Specifica un nome per la tua rete."
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr "Puoi aggiornare le proprietà modificabili della tua rete qui."
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr "Salva modifiche."
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr "Aggiorna rete"
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr "Dettagli rete."
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr "Riepilogo Utilizzo"
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr ""
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Progetti"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr "Modifica utenti"
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr "Visualizza utilizzo"
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr "Crea Progetto"
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr "Modifica projetto"
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr "ID progetto"
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr "Rimuovi"
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr "Rimosso"
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr "Utente"
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr "Utenti"
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr "Impossible recuperare informazioni sul ruolo."
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr "Ruoli"
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr "Utenti per progetto"
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr "Aggiungi al progetto"
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr "Aggiungi nuovi utenti"
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr "Impossibile recuperare lista progetti"
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr "Impossibile recuperare utenti"
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr "Files iniettati"
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr "Volumi"
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr "Security Groups"
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr "Regole dei Security Groups"
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr "Da qui puoi creare un nuovo progetto per organizzare gli utenti."
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr "Impossible recuperare lista utenti"
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr "Aggiungi utente a progetto"
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr "Seleziona il ruolo utente per il progetto."
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr "Aggiungi"
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr "Aggiorna progetto"
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-#, fuzzy
-msgid "Modify Project Quotas"
-msgstr "Quote per i progetti"
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr "Riepilogo utilizzo progetto"
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-#, fuzzy
-msgid "Project Users"
-msgstr "Progetto ed Utente."
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-#, fuzzy
-msgid "Router Name"
-msgstr "Nome del container"
-
-#: dashboards/admin/routers/forms.py:48
-#, fuzzy
-msgid "Failed to get tenants."
-msgstr "Impossible recuperare la lista dei 'tenants'"
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, fuzzy, python-format
-msgid "Failed to create router \"%s\"."
-msgstr "Creazione della rete \"%s\" fallita."
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-#, fuzzy
-msgid "Create Router"
-msgstr "Crea cartella"
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-#, fuzzy
-msgid "Unable to retrieve router list."
-msgstr "Impossible recuperare lista utenti"
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr "Tipo"
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-#, fuzzy
-msgid "Create router"
-msgstr "Crea cartella"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-#, fuzzy
-msgid "Router Overview"
-msgstr "Riepilogo porta"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-#, fuzzy
-msgid "Create a Router"
-msgstr "Crea un Volume"
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-#, fuzzy
-msgid "Router Details"
-msgstr "Dettagli Volume"
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-#, fuzzy
-msgid "Router Detail"
-msgstr "Dettagli Volume"
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-#, fuzzy
-msgid "Set Gateway"
-msgstr "Indirizzo IP del Gateway"
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr "Ruolo"
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr "Impossible creare utente"
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr "Nome"
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr "Progetto principale"
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr "L'utente è stato correttamente aggiornato."
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr "Impossibile aggiornare %(attributes)s per l'utente"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr "Abilita"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr "Disabilita"
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr "Disabilitato"
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-"Impossibile disabilitare l'utente con cui si e' correntemente collegati"
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr "ID utente"
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr "Impossibile aggiornare utente"
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr "Impossibile recuperare ruoli utente"
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, fuzzy, python-format
-msgid "Successfully created volume type: %s"
-msgstr "Chiave pubblica importata correttamente: %s"
-
-#: dashboards/admin/volumes/forms.py:43
-#, fuzzy
-msgid "Unable to create volume type."
-msgstr "Impossible creare utente"
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-#, fuzzy
-msgid "Create Volume Type"
-msgstr "Crea un volume"
-
-#: dashboards/admin/volumes/tables.py:17
-#, fuzzy
-msgid "Volume Type"
-msgstr "Dettagli Volume"
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-#, fuzzy
-msgid "Volume Types"
-msgstr "Volumi"
-
-#: dashboards/admin/volumes/views.py:51
-#, fuzzy
-msgid "Unable to retrieve volume tenant information."
-msgstr "Impossible recuperare informazioni sul volume."
-
-#: dashboards/admin/volumes/views.py:68
-#, fuzzy
-msgid "Unable to retrieve volume types"
-msgstr "Impossible recuperare i dettagli del volume."
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver "
-"to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-#, fuzzy
-msgid "Create a Volume Type"
-msgstr "Crea un Volume"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr "Dettagli Volume"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr "Dettagli Volume"
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr "Gestisci \"Compute\""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr "Accesso e Sicurezza"
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr "Impossible recuperare Security Groups"
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr "Keypairs"
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr "Impossibile recuperare la lista di keypair"
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr "Impossible recuperare indirizzo del Floating IP"
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr "Scarica credenziali EC2"
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr "Scarica file RC per Openstack"
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr "Impossible caricare le credenziali EC2"
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr "Errore nella creazione del file zip: %(exc)s"
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr "Errore nel download del file RC: %s"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr "Impossible assegnare Floating IP"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr "Assegna un IP al progetto"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr "Rilascia"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr "Rilasciato"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr "Associa un 'Floating IP'"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr "Dissocia Floating IP"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr "Floating IP:%s dissociato correttamente"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr "Impossible dissociare Floating IP"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid "Select the IP address you wish to associate with the selected instance."
-msgstr "Specifica l'indirizzo IP che vuoi associare all'istanza selezionata."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-#, fuzzy
-msgid "Instance to be associated"
-msgstr "Dettagli istanza"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr "Seleziona un indirizzo IP."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr "Nessun indirizzo IP disponibile."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-#, fuzzy
-msgid "Select a port"
-msgstr "Seleziona un keypair"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr "Seleziona un istanza"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-#, fuzzy
-msgid "No ports available"
-msgstr "Non disponibile"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr "Nessuna istanza disponibile"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr "Gestisci associazioni con Floating IP"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr "Nome del keypair"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-"I nomi dei keypair possono contenere solo lettere, numeri, underscores e "
-"trattini"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr "Chiave pubblica"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr "Chiave pubblica importata correttamente: %s"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr "Keypair"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr "Importa Keypair"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr "Crea Keypair"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr "Fingerprint"
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr "Impossible create Keypair: %(exc)s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr "Impossible creare 'Security Group'"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr "Protocollo IP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-#, fuzzy
-msgid "Port Range"
-msgstr "Porte"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr "Dal porto"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr "Al porto"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-#, fuzzy
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr "Tipo ICMP al di fuori dell'intervallo (-1, 255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr "Codice"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-#, fuzzy
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr "Codice ICMP al di fuori dell'intervallo (-1, 255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr "Sorgente"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr "Security Group"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-#, fuzzy
-msgid "No security groups available"
-msgstr "Nessun keypair disponibile"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr "Tipo ICMP non valido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr "Codice ICMP non valido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr "Tipo ICMP al di fuori dell'intervallo (-1, 255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr "Codice ICMP al di fuori dell'intervallo (-1, 255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-#, fuzzy
-msgid "The specified port is invalid."
-msgstr "Il numero della porta di origine non è valido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr "Il numero della porta di origine non è valido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr "Il numero della porta di destinazione non è valido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-"Il numero della porta di destinazione deve essere maggiore o uguale del "
-"numero della porta di origine"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr "Impossible aggiungere regola al security group."
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr "Creare un Security Group"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr "Modifica regole"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr "Aggiungi una regola"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr "Regola"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr "Regole"
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr "Impossible recuperare Security Groups"
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr "Accesso e Sicurezza"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr "Alloca un 'Floating IP'"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr "Alloca un floating IP da uno specifico gruppo."
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr "Quote per i progetti"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr "Assegna IP"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the "
-"private key (a .pem file)."
-msgstr ""
-"I keypairs sono credenziali ssh che vengono iniettate nell immagini durante "
-"l'avvio. Alla creazione di un nuovo key pair, la chiave pubblica viene "
-"registrata e la chiave privata scaricata (in un file .pem)"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr "Proteggi ed usa la chiave come faresti con una qualsiasi chiave ssh."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr "Scarica keypair."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-"Il keypair &quot;%(keypair_name)s&quot; dovrebbe essere scaricato "
-"automaticamente. In caso contrario, utilizzare il collegamento sottostante."
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-#, fuzzy
-msgid "Protocol"
-msgstr "Protocollo IP"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range "
-"of ports. Selecting the \"Port Range\" option will provide you with space to "
-"provide both the starting and ending ports for the range. For ICMP rules you "
-"instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr "Modifica regole per il 'Security Group'"
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr "Container"
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr "la slash non è un carattere utilizzabile"
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr "Nome del container"
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr "Container creato con successo"
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr "Cartella creata correttamente."
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr "Impossibile creare il container"
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr "Nome dell' oggetto"
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr "File"
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr "Oggetto caricato con successo"
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr "Impossibile caricare l' oggetto"
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr "Container di destinazione"
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr "Nome dell' oggetto di destinazione"
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr "Impossibile copiare l' oggetto"
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr "Containers"
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr "Creare un Container"
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr "Caricare un oggetto"
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr "Oggetto"
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr "Oggetti"
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr "Copia"
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr "Scarica"
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr "Impossibile recuperare la lista dei containers"
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr "Impossible recuperare lista oggetti"
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr "Impossibile recuperare oggetto"
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr "Impossibile elencare i containers"
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr "Copia oggetto"
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container. "
-"You may also specify a path at which the new copy should live inside of the "
-"selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a "
-"container and these other file system concepts is that containers cannot be "
-"nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for pseudo-"
-"folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr "Immagini e Snapshots"
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr "Impossible recuperare immagini"
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr "Impossibile recuperare le snapshots."
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr "Impossibile recuperare le snapshots del volume."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr "Un URL esterno (HTTP) da cui caricare l'immagine."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-#, fuzzy
-msgid "Image File"
-msgstr "Nome Immagine"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr "Minima dimensione disco (GB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value "
-"defaults to 0 (no minimum)."
-msgstr ""
-"La dimensione minima del disco necessaria per avviare l'immagine. Se non "
-"specificata, questo valore sarà 0 (nessun minimo) per default"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr "RAM minima (MB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr "Pubblica"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr "La tua immagine %s è stata accodata per la creazione"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr "Impossible creare una nuova immagine"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr "Kernel ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr "Ramdisk ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr "Architettura"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr "Impossibile aggiornare immagine: \"%s\""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr "L'immagine è stata correttamente aggiornata."
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr "Avvia"
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr "Immagine"
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr "Impossible recuperare i dettagli dell'immagine"
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr "Impossibile recuperare immagine."
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr "Instance ID"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr "Impossibile recuperare istanza"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr "Sommario Immagine"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr "Creata"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr "Aggiornata"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr "Specifiche"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr "Formato del container"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr "Formato disco"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr "Proprietà personalizzate"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr "Tipo immagine"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-#, fuzzy
-msgid "Volume Snapshot Details"
-msgstr "Dettagli Volume"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-#, fuzzy
-msgid "Volume Snapshot Detail"
-msgstr "Dettagli Volume"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr "Crea un volume"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-#, fuzzy
-msgid "Unable to retrieve snapshot details."
-msgstr "Impossible recuperare informazioni sulle porte"
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr "Termina"
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-#, fuzzy
-msgid "Hard Reboot"
-msgstr "Riavvia"
-
-#: dashboards/project/instances/tables.py:87
-#, fuzzy
-msgid "Hard Rebooted"
-msgstr "Riavviata"
-
-#: dashboards/project/instances/tables.py:103
-#, fuzzy
-msgid "Soft Reboot"
-msgstr "Riavvia"
-
-#: dashboards/project/instances/tables.py:104
-#, fuzzy
-msgid "Soft Rebooted"
-msgstr "Riavviata"
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr "Metti in pausa"
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr "Riprendi"
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr "Messa in pausa"
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr "Ripresa"
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr "Sospendi"
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr "Sospesa"
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr "Avvia istanza"
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr "Modifica istanza"
-
-#: dashboards/project/instances/tables.py:222
-#, fuzzy
-msgid "Edit Security Groups"
-msgstr "Modifica regole per il 'Security Group'"
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-#, fuzzy
-msgid "Console"
-msgstr "Console VNC"
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr "Visualizza Log"
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, fuzzy, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr "Floating IP:%s dissociato correttamente"
-
-#: dashboards/project/instances/tables.py:338
-#, fuzzy
-msgid "Unable to associate floating IP."
-msgstr "Impossible dissociare Floating IP"
-
-#: dashboards/project/instances/tables.py:364
-#, fuzzy, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr "Floating IP:%s dissociato correttamente"
-
-#: dashboards/project/instances/tables.py:367
-#, fuzzy
-msgid "No floating IPs to disassociate."
-msgstr "Gestisci associazioni con Floating IP"
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr "Non disponibile"
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr "Nome istanza"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr "Log"
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr "Impossible recuperare log per istanza \"%s\""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr "Impossible recuperare istanze"
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr "Impossible recuperare la console VNC per l'istanza \"%s\""
-
-#: dashboards/project/instances/views.py:133
-#, fuzzy, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr "Impossible recuperare la console VNC per l'istanza \"%s\""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr "Impossible recuperare dettagli istanza."
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr "Impossible recuperare i dettagli dell'istanza \"%s\""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-#, fuzzy
-msgid "Instance Console"
-msgstr "Totale istanze"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-#, fuzzy
-msgid "Click here to show only console"
-msgstr "Cliccare qui per mostrare solo VNC"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr "Vai"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr "Disco"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-"E' possibile personalizzare l'istanza dopo l'avvio utilizzando le opzioni "
-"qui disponibili."
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-"Il grafico sottostante mostra le risorse utilizzate da questo progetto in "
-"relazione alle quote stabilite per il progetto stesso."
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr "Totale disco"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr "Numero istanze"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-#, fuzzy
-msgid "Total RAM"
-msgstr "Totale disco"
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-#, fuzzy
-msgid "Selected Networks"
-msgstr "Aggiorna rete"
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr "Dettagli istanza"
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr "Progetto ed Utente."
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr "Punto di mount del volume (i.e. 'vda' mounts at '/dev/vda')"
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr "Elimina il volume quando l'istanza viene terminata"
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr "Seleziona volume"
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr "Dimensione dell'immagine da avviare"
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr "Totale istanze"
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr "Numero di istanze da avviare"
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr "Dettagli"
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-"L'avvio istanze multiple è supportato solo per immagini e 'snapshots' di "
-"istanze."
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr "Impossible recuperare immagini pubbliche."
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr "Impossible recuperare immagini per il progetto corrente."
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr "Seleziona un'immagine"
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr "Nessuna immagine disponibile"
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr "Keypair da usare per l'autenticazione"
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr "Avvia l'istanza con i seguenti 'security groups'"
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr "Impossibile recuperare i keypairs"
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr "Seleziona un keypair"
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr "Nessun keypair disponibile"
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr "Impossibile recuperare la lista dei 'security groups'"
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built "
-"(max 16kb)."
-msgstr ""
-"Uno script o un insieme di comandi da eseguire dopo che l'istanza e' stata "
-"assemblata (massimo 16kb)"
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr "Avvia l'istanza con queste reti"
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr "Seleziona le reti per la tua istanza"
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr "Impossibile recuperare reti"
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr "%s istanze"
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr "Istanza"
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-#, fuzzy
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr "Impossible recuperare Security Groups"
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, fuzzy, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr "Impossible aggiungere regola al security group."
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-#, fuzzy
-msgid "All Security Groups"
-msgstr "Security Groups"
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-#, fuzzy
-msgid "Instance Security Groups"
-msgstr "Security Groups"
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-#, fuzzy
-msgid "No security groups found."
-msgstr "Security Groups"
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-#, fuzzy
-msgid "No security groups enabled."
-msgstr "Regole dei Security Groups"
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-#, fuzzy
-msgid "From here you can edit the instance details."
-msgstr "Da qui puoi creare un nuovo progetto per organizzare gli utenti."
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, fuzzy, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr "Impossible recuperare log per istanza \"%s\""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-#, fuzzy
-msgid "Add Pool"
-msgstr "Aggiungi una regola"
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-#, fuzzy
-msgid "Add Member"
-msgstr "Aggiungi nuovi utenti"
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-#, fuzzy
-msgid "Protocol Port"
-msgstr "Protocollo IP"
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-#, fuzzy
-msgid "Unable to retrieve pools list."
-msgstr "Impossible recuperare lista utenti"
-
-#: dashboards/project/loadbalancers/tabs.py:62
-#, fuzzy
-msgid "Unable to retrieve member list."
-msgstr "Impossible recuperare lista utenti"
-
-#: dashboards/project/loadbalancers/tabs.py:79
-#, fuzzy
-msgid "Unable to retrieve monitor list."
-msgstr "Impossibile recuperare la lista dei containers"
-
-#: dashboards/project/loadbalancers/tabs.py:90
-#, fuzzy
-msgid "Pool Details"
-msgstr "Dettagli Volume"
-
-#: dashboards/project/loadbalancers/tabs.py:101
-#, fuzzy
-msgid "Unable to retrieve pool details."
-msgstr "Impossible recuperare informazioni sulle porte"
-
-#: dashboards/project/loadbalancers/tabs.py:106
-#, fuzzy
-msgid "Vip Details"
-msgstr "Dettagli"
-
-#: dashboards/project/loadbalancers/tabs.py:117
-#, fuzzy
-msgid "Unable to retrieve vip details."
-msgstr "Impossible recuperare informazioni sulle porte"
-
-#: dashboards/project/loadbalancers/tabs.py:122
-#, fuzzy
-msgid "Member Details"
-msgstr "Dettagli Volume"
-
-#: dashboards/project/loadbalancers/tabs.py:133
-#, fuzzy
-msgid "Unable to retrieve member details."
-msgstr "Impossible recuperare i dettagli dell'immagine"
-
-#: dashboards/project/loadbalancers/tabs.py:138
-#, fuzzy
-msgid "Monitor Details"
-msgstr "Dettagli rete."
-
-#: dashboards/project/loadbalancers/tabs.py:149
-#, fuzzy
-msgid "Unable to retrieve monitor details."
-msgstr "Impossible recuperare informazioni sulle porte"
-
-#: dashboards/project/loadbalancers/views.py:55
-#, fuzzy
-msgid "Unable to delete monitor."
-msgstr "Impossible recuperare rete."
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-#, fuzzy
-msgid "Unable to delete member."
-msgstr "Impossible creare utente"
-
-#: dashboards/project/loadbalancers/views.py:76
-#, fuzzy
-msgid "Unable to locate vip to delete."
-msgstr "Impossibile creare il container"
-
-#: dashboards/project/loadbalancers/views.py:82
-#, fuzzy
-msgid "Unable to delete vip."
-msgstr "Impossible creare utente"
-
-#: dashboards/project/loadbalancers/views.py:112
-#, fuzzy
-msgid "Unable to retrieve pool subnet."
-msgstr "Impossibile recuperare oggetto"
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-#, fuzzy
-msgid "Select a Subnet"
-msgstr "Seleziona Progetto"
-
-#: dashboards/project/loadbalancers/workflows.py:54
-#, fuzzy
-msgid "Unable to retrieve networks list."
-msgstr "Impossibile recuperare reti"
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-#, fuzzy
-msgid "Select a Protocol"
-msgstr "Seleziona Progetto"
-
-#: dashboards/project/loadbalancers/workflows.py:72
-#, fuzzy
-msgid "PoolDetails"
-msgstr "Dettagli"
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all "
-"members of this pool must be on. Select the protocol and load balancing "
-"method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, fuzzy, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr "Impossibile create rete \"%s\"."
-
-#: dashboards/project/loadbalancers/workflows.py:124
-#, fuzzy
-msgid "Vip Address from Floating IPs"
-msgstr "Associa un 'Floating IP'"
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-#, fuzzy
-msgid "Cookie Name"
-msgstr "Nome del container"
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, fuzzy, python-format
-msgid "Specify a free IP address from %s"
-msgstr "Seleziona un indirizzo IP."
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and "
-"session persistence method for the vip.Specify the max connections allowed. "
-"Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, fuzzy, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr "Impossibile aggiornare immagine: \"%s\""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-#, fuzzy
-msgid "Unable to retrieve pool."
-msgstr "Impossibile recuperare oggetto"
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-#, fuzzy
-msgid "Select members for this pool "
-msgstr "Seleziona il ruolo utente per il progetto."
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-#, fuzzy
-msgid "Select a Pool"
-msgstr "Seleziona Progetto"
-
-#: dashboards/project/loadbalancers/workflows.py:283
-#, fuzzy
-msgid "Unable to retrieve instances list."
-msgstr "Impossible recuperare la lista delle istanze"
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-#, fuzzy
-msgid "MemberDetails"
-msgstr "Dettagli"
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). "
-"Assign a numeric weight for this member Specify the port number the member"
-"(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, fuzzy, python-format
-msgid "Unable to add Member %s."
-msgstr "Impossibile aggiornare immagine: \"%s\""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, fuzzy, python-format
-msgid "No instances available.%s"
-msgstr "Nessuna istanza disponibile"
-
-#: dashboards/project/loadbalancers/workflows.py:349
-#, fuzzy
-msgid "Unable to retrieve ports list."
-msgstr "Impossibile recuperare lista progetti"
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-#, fuzzy
-msgid "Select Type"
-msgstr "Seleziona un'immagine"
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-#, fuzzy
-msgid "MonitorDetails"
-msgstr "Dettagli"
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry "
-"limits required by the monitor. Specify method, URL path, and expected HTTP "
-"codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, fuzzy, python-format
-msgid "Added Monitor \"%s\"."
-msgstr "Rete \"%s\" creata."
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, fuzzy, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr "Impossibile create rete \"%s\"."
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-#, fuzzy
-msgid "Address: "
-msgstr "Indirizzo IP"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-#, fuzzy
-msgid "Protocol Port: "
-msgstr "Protocollo IP"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-#, fuzzy
-msgid "Status: "
-msgstr "Stato"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-#, fuzzy
-msgid "Type: "
-msgstr "Tipo"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-#, fuzzy
-msgid "Name: "
-msgstr "Nome"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-#, fuzzy
-msgid "Description: "
-msgstr "Descrizione:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-#, fuzzy
-msgid "Subnet ID: "
-msgstr "ID sottorete"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-#, fuzzy
-msgid "Protocol: "
-msgstr "Protocollo IP"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-#, fuzzy
-msgid "Cookie Name: "
-msgstr "Nome del container"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-#, fuzzy
-msgid "Add New Member"
-msgstr "Aggiungi nuovi utenti"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-#, fuzzy
-msgid "Add New Monitor"
-msgstr "Aggiungi nuovi utenti"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-#, fuzzy
-msgid "Add New Pool"
-msgstr "Aggiungi nuovi utenti"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-#, fuzzy
-msgid "Network Topology"
-msgstr "ID della rete"
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next "
-"panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-#, fuzzy
-msgid "Subnet Name"
-msgstr "Nome dell' oggetto"
-
-#: dashboards/project/networks/workflows.py:62
-#, fuzzy
-msgid "Subnet Name. This field is optional."
-msgstr "Nome della sottorete (opzionale)"
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr "Indirizzo di rete"
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr "Indirizzo di rete in formato CIDR (es: 192.168.0.0/24)"
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr "Indirizzo IP del gateway (opzionale)"
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP "
-"of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use the "
-"default, leave blank. If you want to use no gateway, check 'Disable Gateway' "
-"below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-#, fuzzy
-msgid "Disable Gateway"
-msgstr "Disabilita"
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-"Puoi creare una sottorete per la nuova rete; in tal caso e' necessario "
-"specificare l'indirizzo di rete. Se intendi creare una rete SENZA una "
-"sottorete, deseleziona la casella \"Crea Sottorete\"."
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-"Specifica l'indirizzo di rete o deseleziona la casella \"Crea Sottorete\""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-"L'indirizzo di rete non è consistente con il versione del protocollo IP"
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-"L'indirizzo del gateway non è consistente con la versione del protocollo IP"
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-#, fuzzy
-msgid "Enable DHCP"
-msgstr "Abilita"
-
-#: dashboards/project/networks/workflows.py:145
-#, fuzzy
-msgid "Allocation Pools"
-msgstr "Assegna IP"
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is &lt;start_ip_address&gt;,&lt;"
-"end_ip_address&gt; (e.g., 192.168.1.100,192.168.1.120) and one entry per "
-"line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is &lt;"
-"destination_cidr&gt;,&lt;nexthop&gt; (e.g., 192.168.200.0/24,10.56.1.254)and "
-"one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr "Rete \"%s\" creata."
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr "Impossibile create rete \"%s\"."
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr "La rete \"%s\" è stata correttamente creata."
-
-#: dashboards/project/networks/workflows.py:269
-#, fuzzy, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr "Creazione della rete \"%s\" fallita."
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr "La sottorete \"%s\" è stata correttamente creata."
-
-#: dashboards/project/networks/workflows.py:329
-#, fuzzy, python-format
-msgid ""
-"Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr "Creazione della sottorete \"%(sub)s\" per la rete \"%(net)s\" fallita."
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, fuzzy, python-format
-msgid "Failed to delete network \"%s\""
-msgstr "Creazione della rete \"%s\" fallita."
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr "Allegato"
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-#, fuzzy
-msgid "Attached Device"
-msgstr "Allegato"
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr "Impossible recuperare dettagli sottorete"
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr "Impossible recuperare dettagli rete"
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, fuzzy, python-format
-msgid "Created subnet \"%s\"."
-msgstr "Rete \"%s\" creata."
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, fuzzy, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr "Impossibile create rete \"%s\"."
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-#, fuzzy
-msgid "Update"
-msgstr "Aggiornata"
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, fuzzy, python-format
-msgid "Updated subnet \"%s\"."
-msgstr "Rete \"%s\" creata."
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, fuzzy, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr "Impossibile aggiornare immagine: \"%s\""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, fuzzy, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr "La sottorete %s é stata correttamente aggiornata"
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, fuzzy, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr "Creazione della sottorete \"%(sub)s\" per la rete \"%(net)s\" fallita."
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr "Riepilogo rete"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-#, fuzzy
-msgid "Provider Network"
-msgstr "Aggiorna rete"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-#, fuzzy
-msgid "Network Type"
-msgstr "Nome della rete"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-#, fuzzy
-msgid "Physical Network"
-msgstr "Aggiorna rete"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr "Dettagli rete:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr "Riepilogo porta"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr "Indirizzo IP fisso"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr "Indirizzo Ip:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr "ID sottorete"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr "Indirizzo MAC"
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-#, fuzzy
-msgid "DHCP Enable"
-msgstr "Abilita"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-#, fuzzy
-msgid "Destination"
-msgstr "Descrizione"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, fuzzy, python-format
-msgid "Unable to delete router \"%s\""
-msgstr "Impossibile create rete \"%s\"."
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-#, fuzzy
-msgid "Gateway"
-msgstr "Indirizzo IP del Gateway"
-
-#: dashboards/project/routers/tables.py:81
-#, fuzzy
-msgid "Gateways"
-msgstr "Indirizzo IP del Gateway"
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-#, fuzzy
-msgid "Unable to retrieve router details."
-msgstr "Impossible recuperare i dettagli del volume."
-
-#: dashboards/project/routers/views.py:77
-#, fuzzy, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr "Impossible recuperare i dettagli dell'istanza \"%s\""
-
-#: dashboards/project/routers/views.py:89
-#, fuzzy, python-format
-msgid "External network \"%s\" not found."
-msgstr "Rete \"%s\" creata."
-
-#: dashboards/project/routers/views.py:105
-#, fuzzy, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr "Impossible recuperare i dettagli dell'istanza \"%s\""
-
-#: dashboards/project/routers/views.py:117
-#, fuzzy, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr "Impossibile create rete \"%s\"."
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-#, fuzzy
-msgid "Router ID"
-msgstr "ID utente"
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, fuzzy, python-format
-msgid "Failed to get network list %s"
-msgstr "Creazione della rete \"%s\" fallita."
-
-#: dashboards/project/routers/ports/forms.py:67
-#, fuzzy
-msgid "Select Subnet"
-msgstr "Seleziona volume"
-
-#: dashboards/project/routers/ports/forms.py:69
-#, fuzzy
-msgid "No subnets available."
-msgstr "Nessuna istanza disponibile"
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, fuzzy, python-format
-msgid "Failed to add_interface %s"
-msgstr "Eliminazione della sottorete %s fallita"
-
-#: dashboards/project/routers/ports/forms.py:118
-#, fuzzy
-msgid "Select network"
-msgstr "Specifica un nome per la tua rete."
-
-#: dashboards/project/routers/ports/forms.py:120
-#, fuzzy
-msgid "No networks available."
-msgstr "Nessun keypair disponibile"
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, fuzzy, python-format
-msgid "Failed to set gateway %s"
-msgstr "Eliminazione della sottorete %s fallita"
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, fuzzy, python-format
-msgid "Failed to delete interface %s"
-msgstr "Eliminazione della sottorete %s fallita"
-
-#: dashboards/project/routers/ports/views.py:50
-#, fuzzy
-msgid "Unable to retrieve router."
-msgstr "Impossibile recuperare utenti"
-
-#: dashboards/project/routers/ports/views.py:82
-#, fuzzy
-msgid "Unable to set gateway."
-msgstr "Impossible creare una nuova immagine"
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-#, fuzzy
-msgid "Encryption"
-msgstr "Descrizione"
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your "
-"quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, fuzzy, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr "Impossibile recuperare le snapshots del volume."
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr "Impossible recuperare i dettagli del volume."
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr "Impossible recuperare informazioni sul volume."
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr "Crea un Volume"
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr "Impostazioni"
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr "Impostazioni utente"
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-"Da qui puoi modificare le impostazioni del cruscotto per il tuo utente."
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr ""
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr ""
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr ""
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr ""
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr ""
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr "Impossible recuperate informazioni di utilizzo."
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-"Stai vedendo dati relativi al futuro, che potrebbero o non potrebbero "
-"esistere."
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr "Scarica riepilogo in formato CSV."
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr "Nome progetto."
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr "Riepilogo utilizzo."
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/ja/LC_MESSAGES/django.mo b/openstack_dashboard/locale/ja/LC_MESSAGES/django.mo
deleted file mode 100644
index a8adaa5f..00000000
--- a/openstack_dashboard/locale/ja/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/ja/LC_MESSAGES/django.po b/openstack_dashboard/locale/ja/LC_MESSAGES/django.po
deleted file mode 100644
index ab0e5652..00000000
--- a/openstack_dashboard/locale/ja/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4713 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Akihiro MOTOKI <amotoki@gmail.com>, 2013
-# masayukig <masayuki.igawa@gmail.com>, 2013
-# masayukig <masayuki.igawa@gmail.com>, 2013
-# Tomoyuki KATO <tomo@dream.daynight.jp>, 2012-2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-05-07 10:27+0000\n"
-"Last-Translator: Akihiro MOTOKI <amotoki@gmail.com>\n"
-"Language-Team: Japanese (http://www.transifex.com/projects/p/openstack/language/ja/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ja\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "Bulgarian (Bulgaria)"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "Czech"
-
-#: settings.py:154
-msgid "English"
-msgstr "English"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Spanish"
-
-#: settings.py:156
-msgid "French"
-msgstr "French"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Italiano"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "日本語"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "Korean (Korea)"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "Dutch (Netherlands)"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Polish"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Portuguese"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "Portuguese"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Simplified Chinese"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Traditional Chinese"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr "未知のインスタンス"
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr "%(type)s (%(backend)s バックエンド)"
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr "%(group)s からポート番号 %(from)s:%(to)s への通信を許可します"
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr "%(cidr)s からポート番号 %(from)s:%(to)s への通信を許可します"
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr "システムパネル"
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "管理"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "名前"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr "仮想 CPU"
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr "メモリー MB"
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr "ルートディスク GB"
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr "一時ディスク GB"
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr "スワップディスク MB"
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr "インスタンスタイプの一覧を取得できません"
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr "\"%s\" という名前はすでに他のインスタンスタイプにより使用されています。"
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr "インスタンスタイプ \"%s\" を作成しました。"
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr "インスタンスタイプを作成できません。"
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr "インスタンスタイプ \"%s\" を更新しました。"
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr "インスタンスタイプを更新できません。"
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr "インスタンスタイプ"
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr "インスタンスタイプ"
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr "インスタンスタイプの作成"
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr "インスタンスタイプの編集"
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr "その他スペックの表示"
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr "%sMB"
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr "インスタンスタイプ名"
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "メモリー"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr "ルートディスク"
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr "一時ディスク"
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr "スワップディスク"
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr "インスタンスタイプ一覧を取得できません。"
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr "インスタンスタイプのデータを取得できません。"
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr "キー"
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr "値"
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr "その他スペック \"%s\" を作成しました。"
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr "インスタンスタイプのその他スペックを作成できません。"
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr "その他スペック \"%s\" を保存しました。"
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr "その他スペックを編集できません。"
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr "その他スペック"
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr "その他スペック"
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr "作成"
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr "編集"
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr "その他スペック"
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr "その他スペックの一覧を取得できません。"
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr "インスタンスタイプのその他スペックのデータを取得できません。"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "説明"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr "ここから新しいインスタンスタイプの大きさを定義できます。"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "取り消し"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr "現在のインスタンスタイプのサイズを変更できます。"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr "注: このインスタンスタイプを使用している既存のインスタンスに割り当てられたリソースには影響しません。"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr "保存"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr "インスタンスタイプのその他スペックの作成"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr "インスタンスタイプに対する新しい \"その他スペック\" のキーと値の組を作成します。"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr "インスタンスタイプのその他スペックの編集"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr "インスタンスタイプに対する新しい \"その他スペック\" のキーと値の組を更新します。"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr "インスタンスタイプのその他スペック"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr "閉じる"
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "イメージ"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr "イメージ名"
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr "イメージの一覧を取得できません。"
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr "イメージの作成"
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr "説明:"
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr "イメージサービスにアップロードするイメージを指定します。"
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr "今のところ HTTP URL 経由で取得できるイメージのみがサポートされています。イメージの場所は Image Service からアクセスできる必要があります。圧縮イメージがサポートされています (.zip および .tar.gz.)。"
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr "注意: "
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr "イメージの場所は、イメージバイナリーへの有効かつ直接の URL である必要があります。 URL がリダイレクトや処理エラーページであった場合、結果的に利用できないイメージが登録されます。"
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr "イメージの作成"
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr "イメージの更新"
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr "イメージのプロパティーを変更します。"
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr "システム情報"
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr "クォータ名"
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr "上限値"
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr "クォータ"
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr "ID"
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr "サービス"
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr "ホスト"
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr "有効化しました"
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr "サービス"
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr "標準のクォータ"
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr "クォータ情報を取得できません。"
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "インスタンス"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr "マイグレーション"
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr "(確認待ちで) マイグレーション予約しました"
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr "インスタンス"
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "プロジェクト"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr "IP アドレス"
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr "サイズ"
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr "状態"
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr "タスク"
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr "稼働状態"
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr "インスタンスの一覧を取得できません。"
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr "インスタンスのプロジェクト情報を取得できません。"
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr "インスタンスのサイズ情報を取得できません。"
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr "すべてのインスタンス"
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr "管理状態"
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr "共有"
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr "外部ネットワーク"
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr "プロジェクトの選択"
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr "ネットワーク %s が正常に作成されました。"
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr "ネットワーク %s の作成に失敗しました"
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr "ID"
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr "ネットワーク %s が正常に更新されました。"
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr "ネットワーク %s の更新に失敗しました"
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "ネットワーク"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr "ネットワーク"
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr "ネットワーク %s の削除に失敗しました"
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr "ネットワークの作成"
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr "ネットワークの編集"
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "ネットワーク名"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr "関連サブネット"
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr "ネットワーク一覧を取得できません。"
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr "サブネット一覧を取得できません。"
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr "ポート一覧を取得できません。"
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr "ネットワーク \"%s\" の詳細を取得できません。"
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "ネットワーク ID"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr "デバイス ID"
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr "デバイス所有者"
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr "ポート %s が正常に作成されました。"
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr "ネットワーク %s のポートの作成に失敗しました"
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr "ポート %s が正常に更新されました。"
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr "ポート %s の更新に失敗しました"
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "ポート"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "ポート"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr "サブネット %s の削除に失敗しました"
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr "ポートの作成"
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr "ポートの編集"
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr "固定 IP"
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr "デバイスを接続しました"
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr "概要"
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr "ポートの詳細を取得できません。"
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr "ネットワークを取得できません。"
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr "サブネット"
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr "サブネット"
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr "サブネットの作成"
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr "サブネットの編集"
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr "CIDR"
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr "IP バージョン"
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr "ゲートウェイ IP"
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr "サブネットのネットワーク %s の取得に失敗しました"
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr "ネットワークの名前を選択してください。"
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr "ネットワークの編集可能なプロパティーをここから更新できます。"
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr "変更の保存"
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr "ネットワークの更新"
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr "ネットワークのポートを作成できます。接続するデバイス ID を指定すると、指定したデバイスが作成されたポートに接続されます。"
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr "ポートの編集可能なプロパティーをここから更新できます。"
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr "ポートの更新"
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr "ネットワークの詳細"
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr "サブネットの更新"
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr "使用状況"
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr "監視"
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "プロジェクト"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr "ユーザーの変更"
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr "使用状況の表示"
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr "プロジェクトの作成"
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr "プロジェクトの編集"
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr "プロジェクト ID"
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr "削除します"
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr "削除しました"
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr "ユーザー"
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr "ユーザー"
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr "役割の情報を取得できません。"
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr "役割"
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr "プロジェクトのユーザー"
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr "プロジェクトへの追加"
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr "新規ユーザーの追加"
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr "プロジェクト情報を取得できません。"
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr "プロジェクト一覧を取得できません。"
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr "ユーザー一覧を取得できません。"
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr "クォータのデフォルト値を取得できません。"
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr "プロジェクトの詳細を取得できません。"
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr "注入されたファイルのバイト数"
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr "メタデータ項目"
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr "注入されたファイル"
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr "ボリューム"
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr "ギガバイト"
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr "メモリー (MB)"
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr "Floating IP"
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr "セキュリティグループ"
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr "セキュリティグループのルール"
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr "クォータ"
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr "ここからプロジェクトのクォータ (上限) を設定できます。"
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr "プロジェクトの情報"
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr "ユーザーをグルーピングする新しいプロジェクトをここから作成できます。"
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr "ユーザー一覧を取得できません。後からもう一度お試しください。"
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr "Keystone において標準の役割 \"%s\" を見つけられませんでした。"
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr "プロジェクトのメンバー"
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr "すべてのユーザー"
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr "ユーザーが見つかりませんでした。"
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr "ユーザーがいません。"
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr "ユーザーの一覧を取得できません。"
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr "新規プロジェクト \"%s\" を作成しました。"
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr "プロジェクト \"%s\" を作成できません。"
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr "%s プロジェクトメンバーの追加とプロジェクトのクォータの設定に失敗しました。"
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr "プロジェクトのクォータを設定できません。"
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr "ここからプロジェクトの詳細を編集できます。"
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr "プロジェクト \"%s\" を変更しました。"
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr "プロジェクト \"%s\" を変更できません。"
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr "現在ログインしているプロジェクトから \"admin\" の役割を削除できません。管理者権限を持つ他のプロジェクトに切り替える、または手動で CLI から役割を削除してください。"
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr "%s プロジェクトのメンバーの変更とプロジェクトのクォータの更新に失敗しました。"
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr "プロジェクトの情報とメンバーを変更しましたが、プロジェクトのクォータを変更できません。"
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr "プロジェクトへの追加"
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr "プロジェクトに対するユーザーの役割を選択します。"
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr "追加"
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr "プロジェクト '%(tenant_name)s' のユーザーを作成します。"
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr "ここからこのプロジェクトに追加する新規ユーザーを作成できます。"
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr "ユーザーの作成"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr "クォータの更新"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr "プロジェクト %(tenant.name)s のクォータ (上限値) を設定できます。"
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr "プロジェクトの更新"
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr "プロジェクトを編集できます。"
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr "このプロジェクトのメンバーの追加・削除を、有効になっている全ユーザーの一覧から行えます。"
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr "新規ユーザーの追加"
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr "プロジェクトのクォータの変更"
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr "プロジェクトの使用量の概要"
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr "プロジェクトの使用状況"
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr "プロジェクトのユーザー"
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr "所属ユーザー"
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr "ルーター名"
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr "プロジェクト一覧を取得できません。"
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr "ルーター \"%s\" を作成できません。"
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr "ルーターの作成"
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr "ルーター"
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr "ルーターの一覧を取得できません。"
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr "種別"
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr "インターフェース"
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr "ルーターの作成"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr "ルーターの概要"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr "外部ゲートウェイの情報"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr "接続された外部ネットワーク"
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr "ルーターの作成"
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr "ルーターの詳細"
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr "ルーターの詳細"
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr "インターフェースの追加"
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr "指定したサブネットをルーターに接続できます。"
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr "インターフェースの追加"
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr "ゲートウェイの設定"
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr "指定した外部ネットワークをルーターに接続できます。外部ネットワークはルーターのデフォルトルートとして扱われます。また、ルーターは外部接続用のゲートウェイとして動作します。"
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr "パスワードが一致しません。"
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr "ユーザー名"
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr "電子メール"
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr "パスワード"
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr "パスワード (確認)"
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr "主プロジェクト"
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr "ロール"
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr "ユーザー \"%s\" を作成しました。"
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr "主プロジェクトへユーザーを追加できません。"
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr "ユーザーを作成できません。"
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr "名前"
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr "電子メール"
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr "主プロジェクト"
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr "ユーザー %s が次のものに対して定義された役割がありません"
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr "パスワード"
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr "ユーザーが正常に更新されました。"
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr "ユーザーの %(attributes)s を更新できません。"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr "有効化"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr "無効化"
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr "無効化しました"
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr "現在ログインしているユーザーを無効化できません。"
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr "ユーザー ID"
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr "ユーザーを更新できません。"
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr "ユーザーの役割を取得できません。"
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr "ここから、新規ユーザーを作成でき、プロジェクトに割り当てられます。"
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr "ユーザーの更新"
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr "ここから、ユーザーのデフォルトプロジェクトを含め、詳細を編集できます。"
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr "ボリューム種別が正常に作成されました: %s"
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr "ボリューム種別を作成できません。"
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr "ボリューム種別の作成"
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr "ボリューム種別"
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr "ボリューム種別"
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr "ボリュームのプロジェクト情報を取得できません。"
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr "ボリューム種別を取得できません。"
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr "\n ボリューム種別によりボリュームの特性がきまります。\n 通常、このボリュームのために使用されるストレージのバックエンドのドライバーによる機能に対応づけられます。\n 例: \"Performance\", \"SSD\", \"Backup\" など\n "
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr "ボリューム種別の作成"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr "ボリュームの詳細"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr "ボリュームの詳細"
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr "Compute の管理"
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr "オブジェクトストア"
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr "アクセスとセキュリティ"
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr "セキュリティグループの一覧を取得できません。"
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr "キーペア"
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr "キーペアの一覧を取得できません。"
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr "Floating IP アドレスを取得できません。"
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr "Floating IP プールを取得できません。"
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr "API アクセス"
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr "EC2 認証情報のダウンロード"
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr "OpenStack RC ファイルのダウンロード"
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr "サービス・エンドポイント"
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr "API エンドポイント"
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr "EC2 認証情報を取得できません。"
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr "zip ファイル %(exc)s の書き込みに失敗しました。"
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr "RC ファイル %s のダウンロードに失敗しました。"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr "プール"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr "Floating IP %(ip)s を確保しました。"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr "Floating IP を確保できません。"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr "Floating IP の確保"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr "解放"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr "解放しました"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr "Floating IP"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr "Floating IP の割り当て"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr "Floating IP の割り当て解除"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr "Floating IP の割り当て解除に成功しました: %s"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr "Floating IP の割り当てを解除できません。"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr "Floating IP プール"
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr "Floating IP プールがありません。"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr "選択されたインスタンスに割り当てたい IP アドレスを選択します。"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr "IP を割り当てるポート"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr "IP を割り当てるインスタンス"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr "IP アドレスを選択してください"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr "利用可能な IP アドレスがありません"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr "ポートを選択してください"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr "インスタンスを選択してください"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr "ポートがありません"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr "インスタンスがありません"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr "Floating IP の割り当ての管理"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr "割り当て"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr "IP アドレス %s を割り当てました。"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr "IP アドレス %s を割り当てられません。"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr "キーペア名"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr "キーペア名では、アルファベット、数字、アンダースコア、ハイフンだけが使用できます。"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr "公開鍵"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr "公開鍵を正常に取り込みました: %s"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr "キーペアをインポートできません。"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr "キーペア"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr "キーペアの取り込み"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr "キーペアの作成"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr "フィンガープリント"
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr "キーペアを作成できません: %(exc)s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr "この項目は必須です。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr "文字列は ASCII 文字および数字のみを含めることができます。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr "セキュリティグループ %s を正常に作成しました。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr "セキュリティグループを作成できません。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr "IP プロトコル"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr "TCP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr "UDP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr "ICMP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr "このルールが適用されるプロトコル。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr "開く"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr "ポート範囲"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr "1 から 65535 までの整数値を入力してください。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr "ポート番号 (下限)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr "ポート番号 (上限)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr "ICMP タイプの値が (-1, 255) の範囲ではありません"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr "コード"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr "ICMP コードが (-1, 255) の範囲ではありません"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr "接続元"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr "セキュリティグループ"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr "許可 IP 範囲を指定するには、\"CIDR\" を選択してください。他のセキュリティグループのすべてのメンバーからアクセスを許可するには、\"セキュリティグループ\" を選択してください。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr "ネットワークアドレス (例: 192.168.0.0/24)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr "セキュリティグループがありません。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr "ICMP タイプが無効です。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr "ICMP コードが無効です。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr "ICMP タイプが (-1, 255) の範囲ではありません"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr "ICMP コードが (-1, 255) の範囲ではありません"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr "指定されたポートは無効です。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr "「下限」ポート番号が無効です。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr "「上限」ポート番号が無効です。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr "「上限」ポート番号は「下限」ポート番号以上でなければいけません。"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr "ルールを正常に追加しました: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr "ルールをセキュリティグループに追加できません。"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr "セキュリティグループの作成"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr "ルールの編集"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr "ルールの追加"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr "ルール"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr "ルール"
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr "セキュリティグループ情報を取得できません。"
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr "%s (カレント)"
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr "アクセスとセキュリティ"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr "Floating IP の確保"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr "指定した Floating IP プールから Floating IP を確保します。"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr "プロジェクトのクォータ"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr "IP の確保"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr "キーペアは、イメージが起動するときに、イメージに挿入される SSH クレデンシャルです。新しいキーペアを作成することにより、公開鍵を登録し、秘密鍵 (.pem ファイル) をダウンロードできます。"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr "通常の SSH 秘密鍵と同じように保護および使用します。"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr "キーペアのダウンロード"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr "キーペア &quot;%(keypair_name)s&quot; が自動的にダウンロードされます。始まらなければ、以下のリンクを使用してください。"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr "キーペア &quot;%(keypair_name)s&quot; のダウンロード"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr "ルールは、セキュリティグループに割り当てられたインスタンスに対して許可する通信を定義します。セキュリティグループルールは 3 つの部分から構成されます:"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr "IP プロトコル"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr "このルールに適用したい IP プロトコルを指定する必要があります。選択肢は TCP, UDP, または ICMP です。"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr "オープンするポート/ポート範囲"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr "TCP および UDP の場合、ポート番号またはポート範囲を選択できます。 \"ポート範囲\" オプションを選択すると、範囲の開始ポートおよび終了ポートを空白区切りで指定できます。ICMP の場合、ICMP タイプおよびコードを空白区切りで指定します。"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr "このルールにより許可される通信のソースを指定する必要があります。IP アドレスブロック (CIDR) またはソースグループ (セキュリティグループ) で指定します。接続元としてセキュリティグループを選択すると、そのセキュリティグループに所属するすべてのインスタンスが、このルールが適用されるすべてのインスタンスにアクセスできるようになります。"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr "ここから新しいセキュリティグループを作成できます"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr "セキュリティグループのルールの編集"
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr "Swift"
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr "コンテナー"
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr "スラッシュ (/) は使用できません。"
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr "コンテナー名"
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr "コンテナーが正常に作成されました。"
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr "フォルダーが正常に作成されました。"
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr "コンテナーを作成できません。"
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr "オブジェクト名"
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr "スラッシュを使うことができます。オブジェクトストアにより擬似フォルダとして取り扱われます。"
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr "ファイル"
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr "オブジェクトが正常にアップロードされました。"
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr "オブジェクトをアップロードできません。"
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr "宛先コンテナー"
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr "宛先オブジェクト名"
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr "\"%(orig)s\" を \"%(dest)s\" に \"%(new)s\" としてコピーします。"
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr "オブジェクトをコピーできません。"
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr "コンテナー"
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr "コンテナーの作成"
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr "コンテナーの表示"
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr "オブジェクトのアップロード"
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr "オブジェクト"
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr "オブジェクト"
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr "コピー"
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr "ダウンロード"
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr "コンテナーの一覧を取得できません。"
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr "オブジェクトの一覧を取得できません。"
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr "オブジェクトを取得できません。"
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr "コンテナーの一覧を表示できません。"
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr "オブジェクトのコピー"
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr "このコンテナーまたは他のコンテナーに保存するために、既存のオブジェクトの新規コピーを作成します。選択したコンテナーの中で稼働する、新規コピーのパスを指定することもできます。"
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr "コンテナーはデータのストレージの区画です。データを整理する手段を提供します。Windows &reg; のフォルダーや UNIX &reg; のディレクトリーのようにコンテナーを考えることができます。コンテナーとこれらのファイルシステムの概念の主な違いは、コンテナーは入れ子にできないことです。しかしながら、アカウントの中に無制限のコンテナーを作成できます。データはコンテナーに保存する必要があります。そのため、データをアップロードする前に、少なくとも一つのコンテナーをアカウントに定義する必要があります。"
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr "オブジェクトのコンテナーへのアップロード"
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr "オブジェクトは、基本的なストレージ・エンティティ、および OpenStack Object Storage システムに保存するファイルを表現するあらゆるオプションのメタデータです。OpenStack Object Storage にデータをアップロードするとき、データはそのまま(圧縮や暗号化はしない)で保存されます。そして、保存場所(コンテナー)、オブジェクトの名前、キー・バリュー組のあらゆるメタデータから構成されます。"
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr "擬似フォルダー"
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr "コンテナーの中では、オブジェクトを擬似フォルダーの中にまとめることができます。これはデスクトップ OS のフォルダーと同じようなものです。オブジェクトの名前において、共通の接頭辞をつけることにより定義される仮想的なものです。スラッシュ (/) 文字がオブジェクトストアにおいて擬似フォルダーの区切り文字として使用されます。"
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr "オブジェクトのアップロード"
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr "イメージとスナップショット"
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr "イメージ一覧を取得できません。"
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr "スナップショット一覧を取得できません。"
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr "ボリューム・スナップショットの一覧を取得できません。"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr "イメージの場所"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr "イメージを読み込む外部 (HTTP) URL。"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr "イメージファイル"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr "形式"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr "AKI - Amazon カーネル・イメージ"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr "AMI - Amazon マシン・イメージ"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr "ARI - Amazon ラムディスク・イメージ"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr "ISO - 光学ディスク・イメージ"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr "QCOW2 - QEMU エミュレーター"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr "最小ディスク (GB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr "イメージを起動するために必要となる最小ディスク容量。指定されなければ、この値の初期値は 0 (最小値なし) です。"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr "最小メモリー (MB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr "パブリック"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr "イメージまたは外部のイメージ位置を指定する必要があります。"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr "イメージと外部イメージを同時に指定できません。"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr "イメージ %s が作成用のキューに追加されました。"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr "新しいイメージを作成できません。"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr "カーネル ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr "RAM ディスク ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr "アーキテクチャー"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr "イメージ \"%s\" を更新できません。"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr "イメージが正常に更新されました。"
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr "起動"
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr "イメージ"
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr "イメージの詳細を取得できません。"
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr "イメージ情報を取得できません。"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr "インスタンス ID"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr "スナップショット名"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr "インスタンス \"%(inst)s\" のスナップショット \"%(name)s\" が作成されました"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr "スナップショットを作成できません。"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr "スナップショット"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr "スナップショット"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr "インスタンスのスナップショット"
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr "インスタンス情報を取得できません。"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr "イメージとスナップショット"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr "イメージの概要"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr "情報"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr "チェックサム"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr "作成日時"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr "更新日時"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr "スペック"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr "格納形式"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr "ディスク形式"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr "カスタム属性"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr "Euca2ools の状態"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr "イメージ種別"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr "イメージの詳細"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr "スナップショットの作成"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr "スナップショットは実行中のインスタンスのディスク状態を保存します。"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr "ボリューム"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr "GB"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr "スナップショットの作成"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr "ボリュームのスナップショットの詳細"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr "ボリュームのスナップショットの詳細"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr "ボリュームのスナップショット"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr "ボリュームのスナップショット"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr "削除予約しました"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr "ボリュームの作成"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr "ボリューム名"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr "スナップショットを取得できません。"
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr "削除"
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr "削除予約しました"
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr "ハードリブート"
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr "リブートしました"
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr "ソフトリブート"
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr "リブートしました"
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr "一時停止"
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr "再開"
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr "一時停止しました"
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr "再開しました"
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr "休止"
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr "休止しました"
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr "インスタンスの起動"
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr "(クォータを超過しました)"
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr "インスタンスの編集"
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr "セキュリティグループの編集"
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr "コンソール"
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr "ログの参照"
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr "容量変更/マイグレーションの確定"
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr "容量変更/マイグレーションの取り消し"
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr "Floating IP の割り当て解除に成功しました: %s"
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr "Floating IP の割り当てを解除できません。"
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr "Floating IP の割り当て解除に成功しました: %s"
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr "利用可能な Floating IP プールがありません。"
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr "%(name)s | %(RAM)s メモリー | %(VCPU)s 仮想 CPU | %(disk)s ディスク"
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr "取得できません"
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr "インスタンス名"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr "ログ"
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr "インスタンス \"%s\" のログを取得できません。"
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr "インスタンス一覧を取得できません。"
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr "インスタンス \"%s\" の VNC コンソールを取得できません。"
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr "インスタンス \"%s\" の SPICE コンソールを取得できません。"
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr "インスタンスの詳細を取り出せません。"
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr "インスタンス \"%s\" の詳細を取り出せません。"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr "インスタンスのコンソール"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr "コンソールがキーボード入力に対応していなければ、以下のグレーのステータスバーをクリックしてください。"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr "コンソールのみを表示するにはここをクリックします"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr "コンソールが現在利用できません。後からもう一度お試しください。"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr "再読み込み"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr "インスタンスのコンソールログ"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr "ログの大きさ"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr "進む"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr "すべてのログの表示"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr "インスタンスの概要"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr "仮想 CPU"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr "ディスク"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr "IP アドレス"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr "ルールが定義されていません。"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr "メタ情報"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr "キー名"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr "接続されているボリューム"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr "接続先"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr "の"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr "ボリュームが接続されていません。"
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr "ここで利用可能なオプションを使用して、起動した後でインスタンスをカスタマイズできます。"
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr "\"カスタマイズ・スクリプト\" 項目は他のシステムにおける \"ユーザーデータ\" と類似しています。"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr "インスタンスを起動するために詳細を指定します。"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr "以下は、このプロジェクトにより使用されているリソースを、プロジェクトのクォータと関連付けて表示します。"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr "インスタンスタイプの詳細"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr "合計ディスク"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr "MB"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr "インスタンス数"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr "仮想 CPU 数"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr "合計メモリー"
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr "利用可能なネットワークから選択済みネットワークに、ボタンを押すかドラッグアンドドロップすることによりネットワークを選択します。同様にドラッグアンドドロップにより NIC の順番を変更できます。"
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr "インスタンスはさまざまな形式のストレージを接続して起動できます。これらのオプションをここから選択できます。"
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr "選択済みネットワーク"
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr "利用可能なネットワーク"
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr "インスタンスの詳細"
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr "プロジェクトとユーザー"
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr "ボリュームから起動しません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr "ボリュームから起動します。"
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr "ボリュームのスナップショットから起動します (新しいボリュームを作成します)。"
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr "ボリュームのオプション"
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr "デバイス名"
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr "ボリュームのマウントポイント (例 'vda' と指定すると '/dev/vda' にマウントされます)。"
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr "終了時に削除します"
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr "インスタンス終了時にボリュームを削除します"
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr "ボリュームを選択してください、または %s を選択してください。"
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr "ボリュームの選択"
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr "ボリュームの一覧を取得できません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr "ボリュームのスナップショットの選択"
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr "ボリュームのスナップショットの一覧を取得できません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr "インスタンス・ソース"
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr "インスタンスのスナップショット"
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr "起動するイメージの容量。"
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr "インスタンス数"
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr "起動するインスタンス数。"
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr "詳細"
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr "利用可能なイメージソースがありません。インスタンスを起動しようとする前に、まずイメージを作成する必要があります。"
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr "インスタンスソースのオプションを選択してください。"
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr "複数インスタンスの起動は、イメージとインスタンスのスナップショットについてのみサポートされています。"
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr "公開イメージの一覧を取得できません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr "このプロジェクト向けのイメージ一覧を取得できません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr "イメージの選択"
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr "利用可能なイメージがありません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr "インスタンスのスナップショットの選択"
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr "利用可能なスナップショットがありません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr "インスタンスタイプの一覧を取得できません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr "クォータ情報を取得できません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr "認証に使用するキーペアを選択してください。"
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr "これらのセキュリティグループでインスタンスを起動します。"
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr "キーペア、セキュリティグループ、および他のメカニズムを通してインスタンスへのアクセスを制御します。"
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr "キーペアの一覧を取得できません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr "キーペアの選択"
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr "利用可能なキーペアがありません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr "セキュリティグループの一覧を取得できません"
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr "カスタマイズ・スクリプト"
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr "インスタンスが構築された後に実行されるスクリプトまたは一組のコマンドです (最大 16 kb)。"
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr "作成後"
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr "少なくとも一つのネットワークを指定する必要があります。"
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr "これらのネットワークでインスタンスを起動します"
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr "ネットワーク"
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr "インスタンスのネットワークを選択します。"
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr "ネットワーク一覧を取得できません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr "名前が \"%(name)s\" の %(count)s を起動しました。"
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr "名前が \"%(name)s\" の %(count)s が起動できません。"
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr "%s インスタンス"
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr "インスタンス"
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr "セキュリティグループの一覧を取得できません。後からもう一度お試しください。"
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr "インスタンス %s の現在のセキュリティグループ一覧を取得できません。"
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr "%d 個のセキュリティグループの更新に失敗しました。"
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr "利用可能なセキュリティグループの一覧から、このプロジェクトへのセキュリティグループを追加および削除できます。"
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr "すべてのセキュリティグループ"
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr "インスタンスのセキュリティグループ"
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr "セキュリティグループがありません。"
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr "有効になっているセキュリティグループがありません。"
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr "ここからインスタンスの詳細を編集できます。"
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr "インスタンス \"%s\" を変更しました。"
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr "インスタンス \"%s\" のログを取得できません。"
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr "負荷分散装置"
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr "プールの追加"
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr "仮想 IP の追加"
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr "メンバーの追加"
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr "モニターの追加"
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr "削除します"
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr "仮想 IP"
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr "仮想 IP"
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr "プール"
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr "モニター"
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr "モニター"
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr "メンバー"
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr "メンバー"
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr "仮想 IP"
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr "ポート番号"
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr "モニタータイプ"
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr "プール一覧を取得できません。"
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr "メンバー一覧を取得できません。"
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr "モニター一覧を取得できません。"
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr "プールの詳細"
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr "プールの詳細を取得できません。"
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr "仮想 IP の詳細"
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr "仮想 IP の詳細を取得できません。"
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr "メンバーの詳細"
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr "メンバーの詳細を取得できません。"
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr "モニターの詳細"
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr "モニターの詳細を取得できません。"
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr "モニターを削除できません。"
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr "まず仮想 IP を削除する必要があります。"
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr "メンバーを削除できません。"
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr "削除する仮想 IP が見つかりません。"
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr "仮想 IP を削除できません。"
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr "プールのサブネットを取得できません。"
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr "負荷分散方式"
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr "サブネットの選択"
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr "ネットワーク一覧を取得できません。"
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr "プロトコルの選択"
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr "プールの詳細"
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr "現在のプロジェクトに対するプールを作成します。\n\nプールの名前および説明を入力します。このプールのすべてのメンバーが所属するサブネットを一つ選択します。このプールのプロトコルおよび負荷分散方式を選択します。管理状態がデフォルトで有効 (チェック済み) になっています。"
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr "プール \"%s\" を追加しました。"
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr "イメージ \"%s\" を追加できません。"
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr "Floating IP から仮想 IP を割り当てる"
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr "セッション永続性"
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr "クッキー名"
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr "セッション永続性が APP_COOKIE の場合には必須です。それ以外の場合は無視されます。"
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr "最大接続数"
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr "%s の未使用の IP アドレスを選択して下さい"
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr "セッション永続性の設定"
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr "現在サポートされていません"
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr "仮想 IP の追加"
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr "このプールの仮想 IP を作成します。仮想 IP の名前と説明を入力します。仮想 IP の IP アドレスとポートを指定します。仮想 IP のプロトコルおよびセッション永続化 (session persistence) 方式を選択します。許可される最大接続数を指定します。管理状態が標準で有効 (チェック済み) になっています。"
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr "仮想 IP \"%s\" を追加しました。"
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr "仮想 IP \"%s\" を更新できません。"
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr "アドレスは一つしか指定できません。仮想 IP %s を追加できません。"
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr "プールを取得できません。"
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr "セッション永続性方式が APP_COOKIE の場合、クッキー名を一緒に指定する必要があります。"
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr "メンバー"
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr "このプールのメンバーを選択します。"
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr "重み"
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr "プールの選択"
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr "インスタンスの一覧を取得できません。"
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr "指定できるサーバがありません。止めるには追加ボタンを押します。"
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr "メンバーの詳細"
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr "メンバーを選択済みプールに追加します。\n\nメンバーとしてプールに追加するインスタンスを一覧から選択してください (複数可)。このメンバーに対する重みを指定してください。メンバーが使用するポート番号を指定してください(例: 80)。"
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr "メンバー \"%s\" を追加しました。"
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr "メンバー \"%s\" を更新できません。"
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr "利用可能なインスタンスがありません。 %s"
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr "ポート一覧を取得できません。"
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr "遅延"
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr "タイムアウト"
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr "最大試行回数 (1〜10)"
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr "HTTP メソッド"
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr "URL"
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr "HTTP ステータスコードの期待値"
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr "タイプを選択してください"
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr "HTTP メソッドを選択してください"
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr "モニターの詳細"
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr "プールのモニターを作成します。\n\n対象のプールおよび監視方法を選択します。モニターで必要な、遅延、タイムアウト、最大試行回数を指定します。メソッド、URL パス、および正常時の HTTP コードの期待値を指定します。"
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr "モニター \"%s\" を追加しました。"
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr "モニター \"%s\" を更新できません。"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr "ID: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr "プロジェクト ID: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr "プール ID:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr "IP アドレス:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr "ポート番号:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr "重み: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr "管理状態有効: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr "ステータス:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr "種別:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr "遅延: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr "タイムアウト: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr "最大試行回数: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr "HTTP メソッド: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr "URL パス: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr "期待されるコード: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr "仮想 IP ID: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr "名前"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr "説明:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr "サブネット ID: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr "プロトコル:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr "負荷分散方式: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr "メンバー: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr "ヘルスモニター: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr "セッション永続性: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr "クッキー名:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr "最大接続数: "
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr "メンバーの追加"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr "モニターの追加"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr "プールの追加"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr "仮想 IP の指定"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr "負荷分散装置"
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr "ネットワークトポロジー"
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr "JavaScript が有効になっている必要があります。"
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr "ネットワーク、ルーター、インスタンスがありません。"
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr "サブネットの追加"
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr "ネットワークの詳細を取得できません。"
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr "ネットワーク名。この項目はオプションです。"
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr "新しいネットワークを作成できます。\n合わせて、このネットワークに割り当てられたサブネットを次のパネルで作成できます。"
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr "サブネット名"
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr "サブネット名。この項目はオプションです。"
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr "ネットワークアドレス"
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr "CIDR 形式のネットワークアドレス (例: 192.168.0.0/24)"
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr "ゲートウェイ IP (オプション)"
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr "ゲートウェイの IP アドレス (例: 192.168.0.254)。初期値はネットワークアドレスの最初の IP です (例: 192.168.0.0/24 の場合 192.168.0.1)。初期値を使用したければ、空白のままにしておきます。ゲートウェイを使用する必要がなければ、下の「ゲートウェイなし」をチェックします。"
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr "ゲートウェイなし"
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr "新しいネットワークに関連付けるサブネットを作成できます。この場合、「ネットワークアドレス」を指定する必要があります。サブネットなしでネットワークを作成したければ、「サブネットの作成」のチェックを外してください。"
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr "「ネットワークアドレス」を指定するか、「サブネットの作成」チェックを外してください。"
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr "ネットワークアドレスと IP バージョンが一致していません。"
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr "ネットワークアドレスにおけるサブネットが小さすぎます (/%s)。"
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr "ゲートウェイの IP アドレスと IP バージョンが一致していません。"
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr "ゲートウェイの IP アドレスを指定するか、「ゲートウェイなし」をチェックしてください。"
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr "DHCP 有効"
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr "IP アドレス割り当てプール"
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr "IP アドレス割り当てプール。&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (例: 192.168.1.100,192.168.1.120) 形式で、各項目を 1 行につき 1 項目記入します。"
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr "DNS サーバー"
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr "このサブネット向けの DNS サーバーの IP アドレス一覧。 1 行につき 1 項目。"
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr "追加のルート設定"
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr "ホストに通知される追加のルート。&lt;destination_cidr&gt;,&lt;nexthop&gt; (例: 192.168.200.0/24,10.56.1.254) 形式の各項目を 1 行につき 1 項目記入します。"
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr "サブネットの追加属性を指定することができます。"
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr "%(field_name)s: 無効な IP アドレス (値=%(ip)s)"
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr "%(field_name)s: 無効な IP アドレス (値=%(network)s)"
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr "開始アドレスと終了アドレスを指定する必要があります (値=%s)"
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr "開始アドレスが終了アドレスより大きい (値=%s)"
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr "追加のルート設定の形式エラー: 宛先 CIDR およびネクストホップを指定する必要があります (値=%s)"
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr "ネットワーク \"%s\" を作成しました。"
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr "ネットワーク \"%s\" の作成に失敗しました。"
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr "ネットワーク \"%s\" が正常に作成されました。"
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr "ネットワーク \"%(network)s\" の作成に失敗しました: %(reason)s"
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr "サブネット \"%s\" が正常に作成されました。"
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr "ネットワーク \"%(net)s\" のサブネット \"%(sub)s\" の作成に失敗しました: %(reason)s"
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr "サブネット作成に失敗したため、作成したネットワーク \"%s\" を削除しました。"
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr "ネットワーク \"%s\" の削除に失敗しました"
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr "接続中"
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr "未接続"
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr "接続中のデバイス"
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr "ポートの詳細を取得できません"
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr "サブネットの詳細を取得できません。"
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr "サブネットの詳細を取得できません。"
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr "ネットワークに割り当てられたサブネットを作成できます。「サブネットの詳細」タブで高度な設定ができます。"
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr "サブネット \"%s\" を作成しました。"
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr "サブネット \"%s\" の作成に失敗しました。"
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr "ゲートウェイの IP アドレス (例: 192.168.0.254)。ゲートウェイを設定するには、具体的なアドレスを指定する必要があります。ゲートウェイを使用する必要がなければ、下の「ゲートウェイなし」をチェックしてください。"
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr "ネットワークに割り当てられたサブネットを更新できます。高度な設定は「サブネットの詳細」タブにあります。"
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr "更新しました"
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr "サブネット \"%s\" を更新しました。"
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr "サブネット \"%s\" を更新できません。"
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr "サブネット \"%s\" が正常に更新できました。"
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr "サブネット \"%(sub)s\" の更新に失敗しました: %(reason)s"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr "ネットワークの概要"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr "プロバイダーネットワーク"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr "ネットワーク種別"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr "物理ネットワーク"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr "セグメント ID"
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr "ネットワークの詳細: "
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr "ポートの概要"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr "固定 IP"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr "IP アドレス:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr "サブネット ID"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr "MAC アドレス"
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr "ポートの詳細"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr "サブネットの概要"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr "IP バージョン"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr "IP アドレス割り当てプール"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr "先頭"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr " - 末尾"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr "DHCP 有効"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr "追加のルート設定"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr "説明"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr " : ネクストホップ"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr "なし"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr "DNS サーバー"
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr "サブネットの詳細"
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr "ルーター"
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr "ルーター \"%s\" を更新できません。"
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr "削除"
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr "削除しました"
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr "ゲートウェイ"
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr "ゲートウェイ"
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr "ルーター \"%(name)s\" のゲートウェイを削除できません: \"%(msg)s\""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr "ルーターの詳細を取得できません。"
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr "外部ネットワーク一覧を取得できません: \"%s\""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr "外部ネットワーク \"%s\" が見つかりませんでした。"
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr "ルーター \"%s\" の詳細を取得できません。"
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr "外部ネットワーク \"%s\" の情報を取得できません。"
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr "ルーター ID"
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr "ネットワーク一覧を取得できません: \"%s\""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr "サブネットの選択"
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr "サブネットがありません。"
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr "インターフェースを追加しました"
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr "インターフェースの追加に失敗しました: %s"
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr "ネットワークの選択"
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr "ネットワークがありません。"
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr "ゲートウェイ・インターフェースを追加しました"
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr "ゲートウェイの設定に失敗しました: %s"
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr "インターフェース"
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr "インタフェースの削除に失敗しました: %s"
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr "ルーター情報を取得できません。"
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr "ゲートウェイを設定できません。"
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr "容量 (GB)"
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr "暗号化"
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr "スナップショットをソースとして使用する"
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr "ボリューム容量はスナップショット容量 (%sGB) 以上でなければいけません。"
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr "指定されたスナップショットを読み込めません。"
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr "スナップショットの選択"
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr "ボリューム容量はスナップショット容量 (%sGB) より小さくできません。"
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr "利用可能なクォータは %(avail)iGB しかないため、 %(req)iGB のボリュームは作成できません。"
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr "すでに利用可能なすべてのボリュームを使用しています。"
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr "ボリュームを作成できません。"
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr "インスタンスへの接続"
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr "接続するインスタンスを選択してください。"
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr "未知のインスタンス (None)"
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr "ボリューム %(vol)s をインスタンス %(inst)s の %(dev)s に接続しています。"
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr "ボリュームを接続できません。"
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr "ボリュームのスナップショット \"%s\" を作成しています"
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr "ボリュームのスナップショットを作成できません。"
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr "ボリューム \"%s\" を削除できません。複数のスナップショットがこのボリュームに依存しています。"
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr "接続の編集"
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr "%sGB"
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr "接続情報を取得できません。"
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr "%(instance)s の %(dev)s に接続しました"
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr "切断します"
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr "切断しています"
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr "インスタンス %(instance_name)s 上の %(dev)s"
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr "ボリュームの詳細を取得できません。"
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr "ボリューム一覧を取得できません。"
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr "ボリューム / インスタンスの接続情報を取得できません。"
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr "ボリューム情報を取得できません。"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr "ボリュームの接続の管理"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr "インスタンスへの接続"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr "ボリュームの接続"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr "ボリュームは、インスタンスに接続できるブロックデバイスです。"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr "ボリュームのクォータ"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr "合計ギガバイト"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr "ボリューム数"
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr "ボリュームのスナップショットの作成"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr "ボリュームの概要"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr "接続状況"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr "未接続"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr "メタデータ"
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr "ボリュームの作成"
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr "ボリュームのスナップショットの作成"
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr "設定"
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr "設定を保存しました。"
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr "ユーザー設定"
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr "ここからユーザー向けダッシュボードの設定を変更できます。"
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "権限がありません"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "ホーム"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "ページが見つかりませんでした"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "お探しのページが見つかりません"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "入力したアドレスが間違っている、またはそのページが移動してしまった。"
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr "内部サーバーエラー"
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr "どこかがおかしくなりました !"
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr "予期しないエラーが発生しました。ページの再読み込みを試してください。解決しなければ、管理者に連絡してください。"
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr "ヘルプ"
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "次の役割でログイン中"
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr "ログアウト"
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr "パスワードは 8 文字から 18 文字である必要があります。"
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr "使用状況を取得できません。"
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr "結果が反映されるまで時間がかかります。しばらくお待ちください。"
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr "概要 CSV ダウンロード"
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr "仮想 CPU 時間"
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr "プロジェクト名"
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr "ディスク GB 時間"
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr "使用状況"
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr "稼働時間"
diff --git a/openstack_dashboard/locale/ka_GE/LC_MESSAGES/django.mo b/openstack_dashboard/locale/ka_GE/LC_MESSAGES/django.mo
deleted file mode 100644
index 73370ee7..00000000
--- a/openstack_dashboard/locale/ka_GE/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/ka_GE/LC_MESSAGES/django.po b/openstack_dashboard/locale/ka_GE/LC_MESSAGES/django.po
deleted file mode 100644
index 928c9aff..00000000
--- a/openstack_dashboard/locale/ka_GE/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4712 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Gabriel Hurley <gabriel@strikeawe.com>, 2012
-# johnpostlethwait <john.postlethwait@gmail.com>, 2012
-# Nika Chkhikvishvili <frrrredo@gmail.com>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ka_GE\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr ""
-
-#: settings.py:153
-msgid "Czech"
-msgstr "ჩეხური"
-
-#: settings.py:154
-msgid "English"
-msgstr "English"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Spanish"
-
-#: settings.py:156
-msgid "French"
-msgstr "French"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Italiano"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Japanese"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr ""
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr ""
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Polish"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Portuguese"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr ""
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Simplified Chinese"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Traditional Chinese"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr "უცნობი ეგზემპლარი"
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr "სისტემური პანელი"
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "ადმინი"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "სახელი"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr "VCPU-ბი"
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr "RAM მბ"
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr "%sმბ"
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "RAM"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr "სვაპ დისკი"
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr "გასაღები"
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr "მნიშვნელობა"
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr "შექმნა"
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr "რედაქტირება"
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "განსაზღვრება"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "უარყოფა"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr "შენახვა"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr "დახურვა"
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "იმიჯები"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr ""
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr "სისტემი სინფორმაცია"
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr "კვოტის სახელი"
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr "ლიმიტი"
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr "კვოტა"
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr "სერვისი"
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr "ჰოსტი"
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr "ჩართული"
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr "სერვისები"
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "ეგზემპლარები"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr "მიგრაცია"
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr "ეგზემპლარი"
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "პროექტი"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr "IP მისამართი"
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr "ზომა"
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr "სტატუსი"
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr "დავალება"
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr "კვების მდგომარეობა"
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr "შეუძლებელია ეგზემპლარების სიის პოვნა"
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr "შეუძლებელია ეგზემპლარის ზომის მოძეიბა"
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr "ყველა ეგზემპლარი"
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr "გაზიარებული"
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr "აირჩიეთ პროექტი"
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr "ქსელი %s წარმატებით შეიქნა."
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr "ID"
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr ""
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "ქსელები"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr "ქსელი"
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr "ქსელის რედაქტირება"
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "ქსელის სახელი"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr ""
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "ქსელის ID"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr "პორტი %s შეიქმნა წარმატებით."
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr "ვერ მოხერხდა %s პორტის განახლება"
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "პორტი"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "პორტები"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr "საბნეტი %s ვერ წაიშალა"
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr "პორტის შექმნა"
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr "პორტის ედიტირება"
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr "ფიქსირებული IP-ბი"
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr "მიმოხილვა"
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr ""
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr "საბნეტი"
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr "საბნეტები"
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr "საბნეტის შექმნა"
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr "საბნეტის რედაქტირება"
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr "CIDR"
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr "IP ვერსია"
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr "ქსელის დეტალები"
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr "მოხმარების ჯამი"
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr "მონიტორინგი"
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "პროექტები"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr "მომხმარებლების რედაქტირება"
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr "მოხმარების ნახვა"
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr "პროექტის შექნა"
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr "პროექტის რედაქტირება"
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr "პროექტის ID"
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr "წაშლა"
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr "წაშლილი"
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr "მომხმარებელი"
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr "მომხმარებლები"
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr "როლები"
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr "მომხმარებლები პროექტისთვის"
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr "პროექტის დამატება"
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr "ახალი მომხმარებლების დამატება"
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr "მოცულობები"
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr "უსაფრთხოების ჯგუფები"
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr "კვოტა"
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr "პროექტის ინფორმაცია"
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr "პროექტის წევრები"
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr "ყველა მომხმარებელი"
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr "მომხმარებლები ვერ მოიძება"
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr "დამატება"
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr "მომხმარებლის შექმნა"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr "კვოტის განახლება"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr "პროექტის განახლება"
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr "ახალი მომხმარებლის დამატება"
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr "პროექტის კვოტების რედაქტირება"
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr "პროექტის მოხმარება"
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr "პროექტის მომხმარებლები"
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr "როუტერის სახელი"
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr "როუტერები"
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr "ტიპი"
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr "მომხმარებლსი სახელი"
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr "ელფოსტა"
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr "პაროლი"
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr "პაროლის დამოწმება"
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr "როლი"
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr "სახელი"
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr "ელფოსტა"
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr "პირველადი პროექტი"
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr "პაროლი"
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr "ჩართვბა"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr "გამორთვა"
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr "გამორთული"
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr "მომხმარებლის ID"
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr ""
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr "მომხმარებლსი განახლება"
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr "წარმატებით შეიქმნა მოცულობის ტიპი: %s"
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr "მოცულობის ტიპის შექმნა"
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr "მოცულობის ტიპი"
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr "მოცულობის ტიპები"
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr "მოცულობის დეტალები"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr "მოცულობის დეტალები"
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr "წვდომები და უსაფრთხოება"
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr "წყვილი გასაღები"
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr "აირჩიეთ ეგზემპლარი"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr "ეგზემპლარები არ არის ხელმისაწვდომი"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr "წყვილი გასარების იმპორტი"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr "წყვილი გასაღების შექმნა"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr "წესი"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr "წესები"
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr "წვდომები დაamp; უსაფრთხოება"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr "პროექტის კვოტები"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr "პროტოკოლი"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr "ფაილი"
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr "ობიექტის ატვირთვა"
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr "ობიექტი"
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr "ობიექტები"
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr "კოპირება"
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr "გადმოტვირთვა"
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr "ფორმატი"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr "ISO - ოპტიკური დიკის გამოსახულება"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr "დიკსი მინიმუმ (გბ)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr "არქიტექტურა"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr "გაშვება"
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr "ეგზემპლარის ID"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr "სნეპშოტი"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr "სნეპშოტები"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr "ეგზემპლარის სნეპშოტი"
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr "ინფო"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr "შეიქმნა"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr "განახლდა"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr "დიკის ფორმატი"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr "მოცულობა"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr "გბ"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr "მოცულობის სნეპშოტი"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr "მოცულობის სნეპშოტები"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr "მოცულობის შექმნა"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr "მოცულობის სახელი"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr "ტერმინაცია"
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr "დაპაუზება"
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr "გაგრძელება"
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr "ეგზემპლარის გაშვება"
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr "ეგზემპლარის რედაქტირება"
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr "კონსოლი"
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr "ლოგის ნახვა"
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr "არ არის ხელმისაწვდომი"
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr "ეგზემპლარის სახელი"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr "ლოგი"
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr "შეუძლებელიია ლოგ ფაილის ჩვენება ეგზემპლარისთვის \"%s\"."
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr "შეუძლებელია ეგზემპლარების ჩვენება."
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr "შეუძლებელია VNC კონსოლის ჩვენება ეგზემპლარისთვის \"%s\"."
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr "შეუძლებელია ეგზემპლარის დეტალების ჩვენება."
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr "ეგზემპლარის კონსოლი"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr "გადატვირთვა"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr "ეგზემპლარის კონსოლის ლოგი"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr "ლოგის სიგრძე"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr "წინ"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr "მთლიანი ლოგის ნახვა"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr "ეგზემპლარის მიმოხილვა"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr "დისკი"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr "მეტა"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr "გასარების სახელი"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr "მიბმული მოცულობები"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr "მიბმულია"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr "მოცულობები არ არის მიბმული."
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr "დისკის ჯამი"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr "მბ"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr "ეგზემპლარების რაოდენობა"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr "RAM ჯამი"
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr "ეგზემპლარის დეტალები"
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr "პროექტი და მომხმარებელი"
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr "არ ჩაირტვირთის მოცულობიდან."
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr "მოცულობიდან ჩატვირთვა."
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr "მოცულობის პარამეტრები."
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr "მოცულობის წაშლა ეგზემპლარის ტერმინაციისას"
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr "აირჩიე მოცულობა"
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr "ეგზემპლარის წყარო"
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr "ეგზემპლარის სნეპშოტი"
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr "ეგზემპლარების რაოდენობა"
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr "გასაშვები ეგზემპლარების რაოდენობა."
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr "დეტალები"
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr "%s ეგზემპლარები"
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr "ეგზემპლარი"
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr "ეგზემპლარის უსაფრთხოების ჯგუფები"
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr "ეგზემპლარები არ არის ხელმისაწვდომი. %s"
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr "სტატუსი:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr "ტიპი:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr "სახელი:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr "პროტოკოლი:"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr "პორტი სმიმოხილვა"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr "ფიქსირებული IP"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr "IP მისამართი:"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr "პორტს დეტალები"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr "არცერთი"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr "როუტერი"
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr "გასუფთავება"
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr "გასუფთავებული"
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr "შეუძლებელია მოცულობის შექმნა."
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr "ეგზემპლარზე მიბმა"
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr "აირჩიე ეგზემპლარი მისაბმელად"
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr "უცნობი ეგზემპლარი (ცარიელი)"
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr "შეუძლებელია მოცულობის მიბმა."
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr "ეგზემპლარზე მიმაგრება"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr "მოცულობის მიბმა"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr "მოცულობის კვოტები"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr "მოცულობების რეოდენობა"
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr "მოცულობის სნეპშოტის შექმნა"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr "მოცულობის მიმოხილვა"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr "მოცულობის შექმნა"
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr "მოცულობის სნეპშოტის შექმნა"
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr "პარამეტრები"
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr "პარამეტრები შენახულია."
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr "მომხმარებლის პარამეტრები"
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "აკრძალულია"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "მთავარი"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "გვერდი ვერ მოიძებნა"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "გვერდი, რომელსაც თქვენ ეძებთ არ არსებობს"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "You may have mistyped the address or the page may have moved."
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr "დახმარება"
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr "შესული ხართ როგორც "
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr "გამოსვლა"
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr "პროექტის სახელი"
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr "დისკი გბ საათი"
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr "მოხმარების ჯამი"
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr "უწყვეტობა"
diff --git a/openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.mo b/openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.mo
deleted file mode 100644
index 666f9139..00000000
--- a/openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.po b/openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.po
deleted file mode 100644
index e6bcc494..00000000
--- a/openstack_dashboard/locale/ko_KR/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4711 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# bluejay.kr <bluejay.ahn@gmail.com>, 2012
-# Sungjin Gang <potopro@gmail.com>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ko_KR\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "불가리아어 (불가리아)"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "체코어"
-
-#: settings.py:154
-msgid "English"
-msgstr "영어"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "스페인어"
-
-#: settings.py:156
-msgid "French"
-msgstr "프랑스어"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "이탈리아어"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "일본어"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "한국어 (한국)"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "네덜란드어"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "폴란드어어"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "포르투갈어"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "포르투갈어"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "중국어-간체"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "중국어-정체"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr "알수없는 인스턴스"
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr "%(type)s (%(backend)s backend)"
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr "%(group)s에서 %(from)s:%(to)s를 허락."
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr "%(cidr)s에서 %(from)s:%(to)s 허용 "
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr "시스템 패널"
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "관리자"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "이름"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr "VCPUs"
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr "RAM MB"
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr "Root Disk GB"
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr "일시적인 Disk GB"
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr "\"%s\" flavor 생성"
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr "Flavor 생성을 할 수 없음."
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr "\"%s\" flavor 업데이트"
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr "Flavor 업데이트를 할 수 없음."
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr "Flavors"
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr "Flavor"
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr "Flavor 생성"
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr "Flavor 수정"
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr "%sMB"
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr "Flavor 이름"
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "RAM"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr "Root Disk"
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr "일시적인 Disk"
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr "Flavor 리스트를 검색 할 수 없음."
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr "Flavor 데이터를 검색할 수 없음."
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "설명"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "취소"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr "저장"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "이미지들"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr "이미지 이름"
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr "이미지 업데이트"
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr "호스트"
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "인스턴스들"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "프로젝트"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr "IP 주소"
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr "크기"
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr "상태"
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr "작업"
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr "전원 상태"
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr ""
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr "모든 인스턴스들"
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr "관리자 상태"
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr "공유"
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr "프로젝트 선택"
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr "ID"
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr "%s 네트워크 업데이트 실패"
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "네트워크들"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr "네트워크"
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr "%s 네트워크를 삭제 실패"
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr "네트워크 생성"
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "네트워크 이름"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr ""
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "네트워크 ID"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr "장치 ID"
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "포트"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "포트들"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr "%s 서브넷 삭제 "
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr ""
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr ""
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "프로젝트"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr ""
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr ""
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr ""
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr ""
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr ""
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr "인스턴스 이름"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "거부했습니다"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "홈"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "페이지를 찾을 수 없습니다"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "찾고 계시는 페이지가 존재하지 않습니다"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "주소를 잘 못 적으셨거나 페이지가 이동되었을 가능성이 있습니다. "
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr "프로젝트 이름"
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/nl_NL/LC_MESSAGES/django.mo b/openstack_dashboard/locale/nl_NL/LC_MESSAGES/django.mo
deleted file mode 100644
index 411bfed3..00000000
--- a/openstack_dashboard/locale/nl_NL/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/nl_NL/LC_MESSAGES/django.po b/openstack_dashboard/locale/nl_NL/LC_MESSAGES/django.po
deleted file mode 100644
index 68098274..00000000
--- a/openstack_dashboard/locale/nl_NL/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4710 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Erik-Martijn Kasimier <erik.kasimier@nouveaumedia.nl>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: nl_NL\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr ""
-
-#: settings.py:153
-msgid "Czech"
-msgstr ""
-
-#: settings.py:154
-msgid "English"
-msgstr "Engels"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Spaans"
-
-#: settings.py:156
-msgid "French"
-msgstr "Frans"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Italiaans"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Japans"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr ""
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr ""
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Pools"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Portugees"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr ""
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Vereenvoudigd Chinees"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Traditioneel Chinees"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr ""
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr ""
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr ""
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr ""
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr ""
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr ""
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr ""
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr ""
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr ""
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Projecten"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr ""
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr ""
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr ""
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr ""
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr ""
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Verboden"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Thuis"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Pagina niet gevonden"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "De pagina waarnaar je op zoek was bestaat niet"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "Wellicht heb je het adres verkeerd getypt of is de pagina verhuisd."
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr ""
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/pl/LC_MESSAGES/django.mo b/openstack_dashboard/locale/pl/LC_MESSAGES/django.mo
deleted file mode 100644
index 1ef444c3..00000000
--- a/openstack_dashboard/locale/pl/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/pl/LC_MESSAGES/django.po b/openstack_dashboard/locale/pl/LC_MESSAGES/django.po
deleted file mode 100644
index 3b36ae95..00000000
--- a/openstack_dashboard/locale/pl/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,5042 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
-"|| n%100>=20) ? 1 : 2)\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr ""
-
-#: settings.py:153
-msgid "Czech"
-msgstr ""
-
-#: settings.py:154
-msgid "English"
-msgstr ""
-
-#: settings.py:155
-msgid "Spanish"
-msgstr ""
-
-#: settings.py:156
-msgid "French"
-msgstr ""
-
-#: settings.py:157
-msgid "Italiano"
-msgstr ""
-
-#: settings.py:158
-msgid "Japanese"
-msgstr ""
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr ""
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr ""
-
-#: settings.py:161
-msgid "Polish"
-msgstr ""
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr ""
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr ""
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr ""
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr ""
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr ""
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-#, fuzzy
-msgid "Unable to get flavor list"
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, fuzzy, python-format
-msgid "Created flavor \"%s\"."
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/flavors/forms.py:74
-#, fuzzy
-msgid "Unable to create flavor."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:110
-#, fuzzy
-msgid "Unable to update flavor."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-#, fuzzy
-msgid "Edit Flavor"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-#, fuzzy
-msgid "Unable to retrieve flavor list."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-#, fuzzy
-msgid "Unable to retrieve flavor data."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, fuzzy, python-format
-msgid "Created extra spec \"%s\"."
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/flavors/extras/forms.py:48
-#, fuzzy
-msgid "Unable to create flavor extra spec."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, fuzzy, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/flavors/extras/forms.py:66
-#, fuzzy
-msgid "Unable to edit extra spec."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-#, fuzzy
-msgid "Create"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-#, fuzzy
-msgid "Unable to retrieve extra spec list."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/flavors/extras/views.py:90
-#, fuzzy
-msgid "Unable to retrieve flavor extra spec data."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-#, fuzzy
-msgid "From here you can define the sizing of a new flavor."
-msgstr "Tutaj można zarządzać użytkownikami i rolami."
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-#, fuzzy
-msgid "From here you can alter the sizing of the current flavor."
-msgstr "Tutaj można zarządzać użytkownikami i rolami."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances "
-"using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-#, fuzzy
-msgid "Edit Flavor Extra Spec"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-#, fuzzy
-msgid "Flavor Extra Specs"
-msgstr "Wolumeny"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "Obrazy"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-#, fuzzy
-msgid "Image Name"
-msgstr "Obrazy"
-
-#: dashboards/admin/images/views.py:56
-#, fuzzy
-msgid "Unable to retrieve image list."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-#, fuzzy
-msgid "Create An Image"
-msgstr "Aktualizuj obraz"
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary. "
-"URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-#, fuzzy
-msgid "Create Image"
-msgstr "Aktualizuj obraz"
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr "Aktualizuj obraz"
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-#, fuzzy
-msgid "From here you can modify different properties of an image."
-msgstr "Tutaj można zarządzać użytkownikami i rolami."
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-#, fuzzy
-msgid "Quotas"
-msgstr "Aktualizuj instncję"
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-#, fuzzy
-msgid "Unable to get quota info."
-msgstr "Nie można ustawić widoczności obrazu na publiczną: %s"
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "Instancje"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-#, fuzzy
-msgid "Instance"
-msgstr "Instancje"
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-#, fuzzy
-msgid "Project"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr ""
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-#, fuzzy
-msgid "Unable to retrieve instance list."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-#, fuzzy
-msgid "Unable to retrieve instance tenant information."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-#, fuzzy
-msgid "Unable to retrieve instance size information."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-#, fuzzy
-msgid "All Instances"
-msgstr "Instancje"
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-#, fuzzy
-msgid "Admin State"
-msgstr "Położenie"
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-#, fuzzy
-msgid "External Network"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-#, fuzzy
-msgid "Select a project"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/networks/forms.py:64
-#, fuzzy, python-format
-msgid "Network %s was successfully created."
-msgstr "Klucz %s został pomyślnie usunięty."
-
-#: dashboards/admin/networks/forms.py:70
-#, fuzzy, python-format
-msgid "Failed to create network %s"
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, fuzzy, python-format
-msgid "Network %s was successfully updated."
-msgstr "Klucz %s został pomyślnie usunięty."
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, fuzzy, python-format
-msgid "Failed to update network %s"
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-#, fuzzy
-msgid "Create Network"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-#, fuzzy
-msgid "Network Name"
-msgstr "Obrazy"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-#, fuzzy
-msgid "Subnets Associated"
-msgstr "Aktualizuj instncję"
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, fuzzy, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, fuzzy, python-format
-msgid "Port %s was successfully created."
-msgstr "Klucz %s został pomyślnie usunięty."
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, fuzzy, python-format
-msgid "Failed to create a port for network %s"
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, fuzzy, python-format
-msgid "Port %s was successfully updated."
-msgstr "Klucz %s został pomyślnie usunięty."
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, fuzzy, python-format
-msgid "Failed to update port %s"
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-#, fuzzy
-msgid "Create Port"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-#, fuzzy
-msgid "Edit Port"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-#, fuzzy
-msgid "Device Attached"
-msgstr "Dołącz wolumen"
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-#, fuzzy
-msgid "Unable to retrieve port details."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-#, fuzzy
-msgid "Unable to retrieve network."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-#, fuzzy
-msgid "Create Subnet"
-msgstr "Wolumeny"
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-#, fuzzy
-msgid "Edit Subnet"
-msgstr "Edytuj role użytkowników"
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, fuzzy, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-#, fuzzy
-msgid "Update Network"
-msgstr "Aktualizuj obraz"
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-#, fuzzy
-msgid "Update Port"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-#, fuzzy
-msgid "Network Detail"
-msgstr "Wolumeny"
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-#, fuzzy
-msgid "Update Subnet"
-msgstr "Aktualizuj instncję"
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr ""
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-#, fuzzy
-msgid "Projects"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-#, fuzzy
-msgid "Create Project"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-#, fuzzy
-msgid "Edit Project"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:113
-#, fuzzy
-msgid "Remove"
-msgstr "Usuń obraz"
-
-#: dashboards/admin/projects/tables.py:114
-#, fuzzy
-msgid "Removed"
-msgstr "Usuń obraz"
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:134
-#, fuzzy
-msgid "Unable to retrieve role information."
-msgstr "Nie można wyrejestrować obrazu: %s"
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:143
-#, fuzzy
-msgid "Users For Project"
-msgstr "Usuń użytkownika z projektu"
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:163
-#, fuzzy
-msgid "Add New Users"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/projects/views.py:70
-#, fuzzy
-msgid "Unable to retrieve project information."
-msgstr "Nie można wyrejestrować obrazu: %s"
-
-#: dashboards/admin/projects/views.py:90
-#, fuzzy
-msgid "Unable to retrieve project list."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/admin/projects/views.py:113
-#, fuzzy
-msgid "Unable to retrieve users."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/projects/views.py:156
-#, fuzzy
-msgid "Unable to retrieve default quota values."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/admin/projects/views.py:185
-#, fuzzy
-msgid "Unable to retrieve project details."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr "Wolumeny"
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-#, fuzzy
-msgid "Security Group Rules"
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/admin/projects/workflows.py:60
-#, fuzzy
-msgid "Quota"
-msgstr "Aktualizuj instncję"
-
-#: dashboards/admin/projects/workflows.py:62
-#, fuzzy
-msgid "From here you can set quotas (max limits) for the project."
-msgstr "Tutaj można edytować wiele ról użytkowników."
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-#, fuzzy
-msgid "Project Info"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-#, fuzzy
-msgid "From here you can create a new project to organize users."
-msgstr "Tutaj można edytować wiele ról użytkowników."
-
-#: dashboards/admin/projects/workflows.py:113
-#, fuzzy
-msgid "Unable to retrieve user list. Please try again later."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-#, fuzzy
-msgid "Project Members"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-#, fuzzy
-msgid "All Users"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-#, fuzzy
-msgid "Unable to retrieve user list."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/projects/workflows.py:203
-#, fuzzy, python-format
-msgid "Created new project \"%s\"."
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/projects/workflows.py:204
-#, fuzzy, python-format
-msgid "Unable to create project \"%s\"."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/admin/projects/workflows.py:248
-#, fuzzy, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/admin/projects/workflows.py:270
-#, fuzzy
-msgid "Unable to set project quotas."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/admin/projects/workflows.py:280
-#, fuzzy
-msgid "From here you can edit the project details."
-msgstr "Tutaj można edytować wiele ról użytkowników."
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, fuzzy, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-#, fuzzy
-msgid "Add User To Project"
-msgstr "Usuń użytkownika z projektu"
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-#, fuzzy
-msgid "From here you can create a new user to add to this project."
-msgstr "Tutaj można edytować wiele ról użytkowników."
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-#, fuzzy
-msgid "Update Quota"
-msgstr "Aktualizuj instncję"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, fuzzy, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr "Tutaj można edytować wiele ról użytkowników."
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-#, fuzzy
-msgid "Update Project"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-#, fuzzy
-msgid "From here you can edit a project."
-msgstr "Tutaj można edytować wiele ról użytkowników."
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-#, fuzzy
-msgid "Add New User"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-#, fuzzy
-msgid "Modify Project Quotas"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-#, fuzzy
-msgid "Project Users"
-msgstr "Usuń projekt"
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-#, fuzzy
-msgid "Users for Project"
-msgstr "Usuń użytkownika z projektu"
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-#, fuzzy
-msgid "Router Name"
-msgstr "Wolumeny"
-
-#: dashboards/admin/routers/forms.py:48
-#, fuzzy
-msgid "Failed to get tenants."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, fuzzy, python-format
-msgid "Failed to create router \"%s\"."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-#, fuzzy
-msgid "Create Router"
-msgstr "Wolumeny"
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-#, fuzzy
-msgid "Unable to retrieve router list."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-#, fuzzy
-msgid "Create router"
-msgstr "Wolumeny"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-#, fuzzy
-msgid "Router Overview"
-msgstr "Instancje"
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-#, fuzzy
-msgid "Connected External Network"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-#, fuzzy
-msgid "Create a Router"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-#, fuzzy
-msgid "Router Details"
-msgstr "Wolumeny"
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-#, fuzzy
-msgid "Router Detail"
-msgstr "Wolumeny"
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:96
-#, fuzzy, python-format
-msgid "User \"%s\" was successfully created."
-msgstr "Klucz %s został pomyślnie usunięty."
-
-#: dashboards/admin/users/forms.py:106
-#, fuzzy
-msgid "Unable to add userto primary project."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/admin/users/forms.py:110
-#, fuzzy
-msgid "Unable to create user."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-#, fuzzy
-msgid "User has been updated successfully."
-msgstr "Wolumen %(id)s %(name)s został pomyślnie utworzony."
-
-#: dashboards/admin/users/forms.py:194
-#, fuzzy, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr "Nie można usunąć klucza: %s"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr ""
-
-#: dashboards/admin/users/views.py:70
-#, fuzzy
-msgid "Unable to update user."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/admin/users/views.py:104
-#, fuzzy
-msgid "Unable to retrieve user roles."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/users/templates/users/_create.html:17
-#, fuzzy
-msgid "From here you can create a new user and assign them to a project."
-msgstr "Tutaj można edytować wiele ról użytkowników."
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-#, fuzzy
-msgid "Update User"
-msgstr "Aktualizuj obraz"
-
-#: dashboards/admin/users/templates/users/_update.html:17
-#, fuzzy
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr "Tutaj można edytować wiele ról użytkowników."
-
-#: dashboards/admin/volumes/forms.py:38
-#, fuzzy, python-format
-msgid "Successfully created volume type: %s"
-msgstr "Nie można utworzyć grupy bezpieczeństwa: %s"
-
-#: dashboards/admin/volumes/forms.py:43
-#, fuzzy
-msgid "Unable to create volume type."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-#, fuzzy
-msgid "Create Volume Type"
-msgstr "Wolumeny"
-
-#: dashboards/admin/volumes/tables.py:17
-#, fuzzy
-msgid "Volume Type"
-msgstr "Wolumeny"
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-#, fuzzy
-msgid "Volume Types"
-msgstr "Wolumeny"
-
-#: dashboards/admin/volumes/views.py:51
-#, fuzzy
-msgid "Unable to retrieve volume tenant information."
-msgstr "Nie można wyrejestrować obrazu: %s"
-
-#: dashboards/admin/volumes/views.py:68
-#, fuzzy
-msgid "Unable to retrieve volume types"
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver "
-"to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-#, fuzzy
-msgid "Create a Volume Type"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-#, fuzzy
-msgid "Volume Details"
-msgstr "Wolumeny"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-#, fuzzy
-msgid "Volume Detail"
-msgstr "Wolumeny"
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-#, fuzzy
-msgid "Unable to retrieve security groups."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:66
-#, fuzzy
-msgid "Unable to retrieve keypair list."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-#, fuzzy
-msgid "Unable to retrieve floating IP addresses."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-#, fuzzy
-msgid "Unable to retrieve floating IP pools."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-#, fuzzy
-msgid "Download EC2 Credentials"
-msgstr "Wyślij dane uwierzytelniające"
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-#, fuzzy
-msgid "Download OpenStack RC File"
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-#, fuzzy
-msgid "Unable to fetch EC2 credentials."
-msgstr "Wygeneruj dane uwierzytelniające x509."
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, fuzzy, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr "tworzenie użytkownika %s..."
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, fuzzy, python-format
-msgid "Error Downloading RC File: %s"
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, fuzzy, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-#, fuzzy
-msgid "Unable to allocate Floating IP."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-#, fuzzy
-msgid "Allocate IP To Project"
-msgstr "Usuń projekt"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-#, fuzzy
-msgid "Unable to disassociate floating IP."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid "Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-#, fuzzy
-msgid "Port to be associated"
-msgstr "Aktualizuj instncję"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-#, fuzzy
-msgid "Instance to be associated"
-msgstr "Instancje"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-#, fuzzy
-msgid "Select an IP address"
-msgstr "Usuń projekt"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-#, fuzzy
-msgid "No IP addresses available"
-msgstr "brak dostępnych"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-#, fuzzy
-msgid "Select a port"
-msgstr "Usuń projekt"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-#, fuzzy
-msgid "Select an instance"
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-#, fuzzy
-msgid "No ports available"
-msgstr "brak dostępnych"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-#, fuzzy
-msgid "No instances available"
-msgstr "brak dostępnych"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-#, fuzzy
-msgid "Associate"
-msgstr "Aktualizuj instncję"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, fuzzy, python-format
-msgid "Unable to associate IP address %s."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-#, fuzzy
-msgid "Public Key"
-msgstr "Uczyń publicznym"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-#, fuzzy
-msgid "Unable to import keypair."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, fuzzy, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, fuzzy, python-format
-msgid "Successfully created security group: %s"
-msgstr "Nie można utworzyć grupy bezpieczeństwa: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-#, fuzzy
-msgid "Unable to create security group."
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-#, fuzzy
-msgid "Security Group"
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-#, fuzzy
-msgid "No security groups available"
-msgstr "brak dostępnych"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, fuzzy, python-format
-msgid "Successfully added rule: %s"
-msgstr "Pomyślnie zmodyfikowano projekt %(proj)s."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-#, fuzzy
-msgid "Unable to add rule to security group."
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-#, fuzzy
-msgid "Create Security Group"
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-#, fuzzy
-msgid "Edit Rules"
-msgstr "Edytuj role użytkowników"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-#, fuzzy
-msgid "Rules"
-msgstr "Edytuj role użytkowników"
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-#, fuzzy
-msgid "Unable to retrieve security group."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-#, fuzzy
-msgid "Allocate Floating IP"
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-#, fuzzy
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the "
-"private key (a .pem file)."
-msgstr ""
-"Pary kluczy to dane uwierzytelniające ssh, które są wstrzykiwane do "
-"instancji podczas uruchomienia. Utworzenie nowej pary rejestruje klucz "
-"publiczny umożliwia pobranie klucza prywatnego (pliku pem). <em>Należy "
-"chronić i używać ten klucza tak jak normalnego klucza prywantego.</em>"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range "
-"of ports. Selecting the \"Port Range\" option will provide you with space to "
-"provide both the starting and ending ports for the range. For ICMP rules you "
-"instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-#, fuzzy
-msgid "From here you can create a new security group"
-msgstr "Tutaj można edytować wiele ról użytkowników."
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-#, fuzzy
-msgid "Edit Security Group Rules"
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-#, fuzzy
-msgid "Container"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-#, fuzzy
-msgid "Container created successfully."
-msgstr "Wolumen %(id)s %(name)s został pomyślnie utworzony."
-
-#: dashboards/project/containers/forms.py:68
-#, fuzzy
-msgid "Folder created successfully."
-msgstr "Wolumen %(id)s %(name)s został pomyślnie utworzony."
-
-#: dashboards/project/containers/forms.py:71
-#, fuzzy
-msgid "Unable to create container."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:97
-#, fuzzy
-msgid "Object was successfully uploaded."
-msgstr "Grupa bezpieczeństwa %s została pomyślnie usunięta."
-
-#: dashboards/project/containers/forms.py:100
-#, fuzzy
-msgid "Unable to upload object."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-#, fuzzy
-msgid "View Container"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-#, fuzzy
-msgid "Object"
-msgstr "Usuń projekt"
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr ""
-
-#: dashboards/project/containers/views.py:53
-#, fuzzy
-msgid "Unable to retrieve container list."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/containers/views.py:83
-#, fuzzy
-msgid "Unable to retrieve object list."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/containers/views.py:168
-#, fuzzy
-msgid "Unable to retrieve object."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/containers/views.py:203
-#, fuzzy
-msgid "Unable to list containers."
-msgstr "Nie można usunąć klucza: %s"
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container. "
-"You may also specify a path at which the new copy should live inside of the "
-"selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a "
-"container and these other file system concepts is that containers cannot be "
-"nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for pseudo-"
-"folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-#, fuzzy
-msgid "Images & Snapshots"
-msgstr "Instancje"
-
-#: dashboards/project/images_and_snapshots/views.py:64
-#, fuzzy
-msgid "Unable to retrieve images."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/images_and_snapshots/views.py:75
-#, fuzzy
-msgid "Unable to retrieve snapshots."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-#, fuzzy
-msgid "Unable to retrieve volume snapshots."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-#, fuzzy
-msgid "Image Location"
-msgstr "Położenie"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-#, fuzzy
-msgid "Image File"
-msgstr "Obrazy"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value "
-"defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-#, fuzzy
-msgid "Public"
-msgstr "Uczyń publicznym"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-#, fuzzy
-msgid "Unable to create new image."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, fuzzy, python-format
-msgid "Unable to update image \"%s\"."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-#, fuzzy
-msgid "Image was successfully updated."
-msgstr "Obraz %s został pomyślnie wyrejestrowany."
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-#, fuzzy
-msgid "Launch"
-msgstr "Uruchom obraz"
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-#, fuzzy
-msgid "Image"
-msgstr "Obrazy"
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-#, fuzzy
-msgid "Unable to retrieve image details."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-#, fuzzy
-msgid "Unable to retrieve image."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-#, fuzzy
-msgid "Instance ID"
-msgstr "ID instancji:"
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-#, fuzzy
-msgid "Unable to create snapshot."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-#, fuzzy
-msgid "Instance Snapshots"
-msgstr "Instancje"
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-#, fuzzy
-msgid "Unable to retrieve instance."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-#, fuzzy
-msgid "Image Overview"
-msgstr "Instancje"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-#, fuzzy
-msgid "Created"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-#, fuzzy
-msgid "Updated"
-msgstr "Aktualizuj obraz"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-#, fuzzy
-msgid "Image Type"
-msgstr "Obrazy"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-#, fuzzy
-msgid "Volume"
-msgstr "Wolumeny"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-#, fuzzy
-msgid "Volume Snapshot Details"
-msgstr "Wolumeny"
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-#, fuzzy
-msgid "Volume Snapshot Detail"
-msgstr "Wolumeny"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-#, fuzzy
-msgid "Volume Snapshot"
-msgstr "Wolumeny"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-#, fuzzy
-msgid "Volume Snapshots"
-msgstr "Wolumeny"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-#, fuzzy
-msgid "Create Volume"
-msgstr "Wolumeny"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-#, fuzzy
-msgid "Volume Name"
-msgstr "Wolumeny"
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-#, fuzzy
-msgid "Unable to retrieve snapshot details."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-#, fuzzy
-msgid "Launch Instance"
-msgstr "Uruchom obraz"
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr "Edytuj instancję"
-
-#: dashboards/project/instances/tables.py:222
-#, fuzzy
-msgid "Edit Security Groups"
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, fuzzy, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr "Pomyślnie zmodyfikowano projekt %(proj)s."
-
-#: dashboards/project/instances/tables.py:338
-#, fuzzy
-msgid "Unable to associate floating IP."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/instances/tables.py:364
-#, fuzzy, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-#, fuzzy
-msgid "Not available"
-msgstr "brak dostępnych"
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-#, fuzzy
-msgid "Instance Name"
-msgstr "Instancje"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, fuzzy, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr "Nie można zaktualizować instancji %(inst)s: %(msg)s"
-
-#: dashboards/project/instances/views.py:58
-#, fuzzy
-msgid "Unable to retrieve instances."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/instances/views.py:121
-#, fuzzy, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr "Nie można zaktualizować instancji %(inst)s: %(msg)s"
-
-#: dashboards/project/instances/views.py:133
-#, fuzzy, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr "Nie można zaktualizować instancji %(inst)s: %(msg)s"
-
-#: dashboards/project/instances/views.py:154
-#, fuzzy
-msgid "Unable to retrieve instance details."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/instances/views.py:190
-#, fuzzy, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-#, fuzzy
-msgid "Instance Console"
-msgstr "Instancje"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-#, fuzzy
-msgid "console is currently unavailable. Please try again later."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-#, fuzzy
-msgid "Instance Console Log"
-msgstr "Instancje"
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-#, fuzzy
-msgid "Instance Overview"
-msgstr "Instancje"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-#, fuzzy
-msgid "Key Name"
-msgstr "Obrazy"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-#, fuzzy
-msgid "Volumes Attached"
-msgstr "Dołącz wolumen"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-#, fuzzy
-msgid "Attached To"
-msgstr "Dołącz wolumen"
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-#, fuzzy
-msgid "Flavor Details"
-msgstr "Wolumeny"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-#, fuzzy
-msgid "Number of Instances"
-msgstr "Instancje"
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-#, fuzzy
-msgid "Selected Networks"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-#, fuzzy
-msgid "Available networks"
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-#, fuzzy
-msgid "Instance Detail"
-msgstr "ID instancji:"
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-#, fuzzy
-msgid "Project & User"
-msgstr "Usuń projekt"
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-#, fuzzy
-msgid "Volume Options"
-msgstr "Wolumeny"
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-#, fuzzy
-msgid "Delete on Terminate"
-msgstr "Usuń projekt"
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-#, fuzzy
-msgid "Select Volume"
-msgstr "Wolumeny"
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-#, fuzzy
-msgid "Unable to retrieve list of volumes."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-#, fuzzy
-msgid "Select Volume Snapshot"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-#, fuzzy
-msgid "Unable to retrieve list of volume snapshots."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-#, fuzzy
-msgid "Instance Source"
-msgstr "Instancje"
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-#, fuzzy
-msgid "Instance Snapshot"
-msgstr "Instancje"
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-#, fuzzy
-msgid "Instance Count"
-msgstr "Instancje"
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-#, fuzzy
-msgid "Details"
-msgstr "Wolumeny"
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-#, fuzzy
-msgid "Unable to retrieve public images."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-#, fuzzy
-msgid "Unable to retrieve images for the current project."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-#, fuzzy
-msgid "Select Image"
-msgstr "Wolumeny"
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-#, fuzzy
-msgid "No images available."
-msgstr "brak dostępnych"
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-#, fuzzy
-msgid "Select Instance Snapshot"
-msgstr "Instancje"
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-#, fuzzy
-msgid "No snapshots available."
-msgstr "brak dostępnych"
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-#, fuzzy
-msgid "Unable to retrieve instance flavors."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-#, fuzzy
-msgid "Unable to retrieve quota information."
-msgstr "Nie można wyrejestrować obrazu: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-#, fuzzy
-msgid "Launch instance in these security groups."
-msgstr "Nie można utworzyć grupy bezpieczeństwa: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-#, fuzzy
-msgid "Unable to retrieve keypairs."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-#, fuzzy
-msgid "Select a keypair"
-msgstr "Usuń projekt"
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-#, fuzzy
-msgid "No keypairs available."
-msgstr "brak dostępnych"
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-#, fuzzy
-msgid "Unable to retrieve list of security groups"
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built "
-"(max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-#, fuzzy
-msgid "Launch instance withthese networks"
-msgstr "Nie można utworzyć grupy bezpieczeństwa: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-#, fuzzy
-msgid "Select networks for your instance."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-#, fuzzy
-msgid "Unable to retrieve networks."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, fuzzy, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, fuzzy, python-format
-msgid "%s instances"
-msgstr "Instancje"
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-#, fuzzy
-msgid "instance"
-msgstr "Instancje"
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-#, fuzzy
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, fuzzy, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-#, fuzzy
-msgid "All Security Groups"
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-#, fuzzy
-msgid "Instance Security Groups"
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-#, fuzzy
-msgid "No security groups found."
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-#, fuzzy
-msgid "No security groups enabled."
-msgstr "Grupy bezpieczeństwa"
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-#, fuzzy
-msgid "From here you can edit the instance details."
-msgstr "Tutaj można edytować wiele ról użytkowników."
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, fuzzy, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr "Nie można zaktualizować instancji %(inst)s: %(msg)s"
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-#, fuzzy
-msgid "Add Pool"
-msgstr "Usuń projekt"
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-#, fuzzy
-msgid "Add Member"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-#, fuzzy
-msgid "Members"
-msgstr "Usuń projekt"
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-#, fuzzy
-msgid "Unable to retrieve pools list."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/loadbalancers/tabs.py:62
-#, fuzzy
-msgid "Unable to retrieve member list."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/loadbalancers/tabs.py:79
-#, fuzzy
-msgid "Unable to retrieve monitor list."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/loadbalancers/tabs.py:90
-#, fuzzy
-msgid "Pool Details"
-msgstr "Wolumeny"
-
-#: dashboards/project/loadbalancers/tabs.py:101
-#, fuzzy
-msgid "Unable to retrieve pool details."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/loadbalancers/tabs.py:106
-#, fuzzy
-msgid "Vip Details"
-msgstr "Wolumeny"
-
-#: dashboards/project/loadbalancers/tabs.py:117
-#, fuzzy
-msgid "Unable to retrieve vip details."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/loadbalancers/tabs.py:122
-#, fuzzy
-msgid "Member Details"
-msgstr "Wolumeny"
-
-#: dashboards/project/loadbalancers/tabs.py:133
-#, fuzzy
-msgid "Unable to retrieve member details."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/loadbalancers/tabs.py:138
-#, fuzzy
-msgid "Monitor Details"
-msgstr "Wolumeny"
-
-#: dashboards/project/loadbalancers/tabs.py:149
-#, fuzzy
-msgid "Unable to retrieve monitor details."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/loadbalancers/views.py:55
-#, fuzzy
-msgid "Unable to delete monitor."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-#, fuzzy
-msgid "Unable to delete member."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/loadbalancers/views.py:76
-#, fuzzy
-msgid "Unable to locate vip to delete."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/loadbalancers/views.py:82
-#, fuzzy
-msgid "Unable to delete vip."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/loadbalancers/views.py:112
-#, fuzzy
-msgid "Unable to retrieve pool subnet."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-#, fuzzy
-msgid "Select a Subnet"
-msgstr "Usuń projekt"
-
-#: dashboards/project/loadbalancers/workflows.py:54
-#, fuzzy
-msgid "Unable to retrieve networks list."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-#, fuzzy
-msgid "Select a Protocol"
-msgstr "Usuń projekt"
-
-#: dashboards/project/loadbalancers/workflows.py:72
-#, fuzzy
-msgid "PoolDetails"
-msgstr "Wolumeny"
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all "
-"members of this pool must be on. Select the protocol and load balancing "
-"method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, fuzzy, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-#, fuzzy
-msgid "Cookie Name"
-msgstr "Wolumeny"
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, fuzzy, python-format
-msgid "Specify a free IP address from %s"
-msgstr "Usuń projekt"
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and "
-"session persistence method for the vip.Specify the max connections allowed. "
-"Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, fuzzy, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-#, fuzzy
-msgid "Unable to retrieve pool."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-#, fuzzy
-msgid "Select a Pool"
-msgstr "Usuń projekt"
-
-#: dashboards/project/loadbalancers/workflows.py:283
-#, fuzzy
-msgid "Unable to retrieve instances list."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-#, fuzzy
-msgid "MemberDetails"
-msgstr "Wolumeny"
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). "
-"Assign a numeric weight for this member Specify the port number the member"
-"(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, fuzzy, python-format
-msgid "Unable to add Member %s."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, fuzzy, python-format
-msgid "No instances available.%s"
-msgstr "brak dostępnych"
-
-#: dashboards/project/loadbalancers/workflows.py:349
-#, fuzzy
-msgid "Unable to retrieve ports list."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-#, fuzzy
-msgid "Select Type"
-msgstr "Wolumeny"
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-#, fuzzy
-msgid "MonitorDetails"
-msgstr "Wolumeny"
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry "
-"limits required by the monitor. Specify method, URL path, and expected HTTP "
-"codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, fuzzy, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-#, fuzzy
-msgid "Address: "
-msgstr "Usuń projekt"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-#, fuzzy
-msgid "Admin State Up: "
-msgstr "Położenie"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-#, fuzzy
-msgid "Subnet ID: "
-msgstr "Wolumeny"
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-#, fuzzy
-msgid "Add New Member"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-#, fuzzy
-msgid "Add New Monitor"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-#, fuzzy
-msgid "Add New Pool"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-#, fuzzy
-msgid "Network Topology"
-msgstr "Wolumeny"
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-#, fuzzy
-msgid "Unable to retrieve network details."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next "
-"panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-#, fuzzy
-msgid "Subnet Name"
-msgstr "Wolumeny"
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP "
-"of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use the "
-"default, leave blank. If you want to use no gateway, check 'Disable Gateway' "
-"below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-#, fuzzy
-msgid "Allocation Pools"
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is &lt;start_ip_address&gt;,&lt;"
-"end_ip_address&gt; (e.g., 192.168.1.100,192.168.1.120) and one entry per "
-"line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is &lt;"
-"destination_cidr&gt;,&lt;nexthop&gt; (e.g., 192.168.200.0/24,10.56.1.254)and "
-"one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, fuzzy, python-format
-msgid "Unable to create network \"%s\"."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/networks/workflows.py:265
-#, fuzzy, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr "Klucz %s został pomyślnie usunięty."
-
-#: dashboards/project/networks/workflows.py:269
-#, fuzzy, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/networks/workflows.py:325
-#, fuzzy, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr "Klucz %s został pomyślnie usunięty."
-
-#: dashboards/project/networks/workflows.py:329
-#, fuzzy, python-format
-msgid ""
-"Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, fuzzy, python-format
-msgid "Failed to delete network \"%s\""
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/networks/ports/tables.py:39
-#, fuzzy
-msgid "Attached"
-msgstr "Dołącz wolumen"
-
-#: dashboards/project/networks/ports/tables.py:41
-#, fuzzy
-msgid "Detached"
-msgstr "Wolumeny"
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-#, fuzzy
-msgid "Attached Device"
-msgstr "Dołącz wolumen"
-
-#: dashboards/project/networks/ports/views.py:53
-#, fuzzy
-msgid "Unable to retrieve port details"
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/networks/subnets/tabs.py:42
-#, fuzzy
-msgid "Unable to retrieve subnet details."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/networks/subnets/views.py:71
-#, fuzzy
-msgid "Unable to retrieve subnet details"
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, fuzzy, python-format
-msgid "Created subnet \"%s\"."
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, fuzzy, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-#, fuzzy
-msgid "Update"
-msgstr "Aktualizuj obraz"
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, fuzzy, python-format
-msgid "Updated subnet \"%s\"."
-msgstr "Aktualizuj instncję"
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, fuzzy, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, fuzzy, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr "Klucz %s został pomyślnie usunięty."
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, fuzzy, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-#, fuzzy
-msgid "Network Overview"
-msgstr "Instancje"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-#, fuzzy
-msgid "Provider Network"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-#, fuzzy
-msgid "Network Type"
-msgstr "Obrazy"
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-#, fuzzy
-msgid "Physical Network"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-#, fuzzy
-msgid "Network Detail: "
-msgstr "Wolumeny"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-#, fuzzy
-msgid "Port Overview"
-msgstr "Instancje"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-#, fuzzy
-msgid "IP address:"
-msgstr "Usuń projekt"
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-#, fuzzy
-msgid "Port Detail"
-msgstr "Wolumeny"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-#, fuzzy
-msgid "Subnet Overview"
-msgstr "Instancje"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-#, fuzzy
-msgid "Subnet Detail"
-msgstr "Wolumeny"
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, fuzzy, python-format
-msgid "Unable to delete router \"%s\""
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-#, fuzzy
-msgid "Unable to retrieve router details."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/routers/views.py:77
-#, fuzzy, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, fuzzy, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/routers/views.py:117
-#, fuzzy, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, fuzzy, python-format
-msgid "Failed to get network list %s"
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/routers/ports/forms.py:67
-#, fuzzy
-msgid "Select Subnet"
-msgstr "Wolumeny"
-
-#: dashboards/project/routers/ports/forms.py:69
-#, fuzzy
-msgid "No subnets available."
-msgstr "brak dostępnych"
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, fuzzy, python-format
-msgid "Failed to add_interface %s"
-msgstr "Nie można zaktualizować obrazu: %s"
-
-#: dashboards/project/routers/ports/forms.py:118
-#, fuzzy
-msgid "Select network"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/routers/ports/forms.py:120
-#, fuzzy
-msgid "No networks available."
-msgstr "brak dostępnych"
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, fuzzy, python-format
-msgid "Failed to set gateway %s"
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, fuzzy, python-format
-msgid "Failed to delete interface %s"
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/routers/ports/views.py:50
-#, fuzzy
-msgid "Unable to retrieve router."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/routers/ports/views.py:82
-#, fuzzy
-msgid "Unable to set gateway."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-#, fuzzy
-msgid "Unable to load the specified snapshot."
-msgstr "Nie można utworzyć klucza: %s"
-
-#: dashboards/project/volumes/forms.py:94
-#, fuzzy
-msgid "Choose a snapshot"
-msgstr "Wolumeny"
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your "
-"quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-#, fuzzy
-msgid "Unable to create volume."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/volumes/forms.py:167
-#, fuzzy
-msgid "Attach to Instance"
-msgstr "Uruchom obraz"
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-#, fuzzy
-msgid "Unable to attach volume."
-msgstr "Nie można dołączyć wolumenu: %s"
-
-#: dashboards/project/volumes/forms.py:259
-#, fuzzy, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr "tworzenie użytkownika %s..."
-
-#: dashboards/project/volumes/forms.py:265
-#, fuzzy
-msgid "Unable to create volume snapshot."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/volumes/tables.py:48
-#, fuzzy, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/volumes/tables.py:68
-#, fuzzy
-msgid "Edit Attachments"
-msgstr "Dołącz wolumen"
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-#, fuzzy
-msgid "Unable to retrieve attachment information."
-msgstr "Nie można wyrejestrować obrazu: %s"
-
-#: dashboards/project/volumes/tables.py:127
-#, fuzzy, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr "Uruchom obraz"
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-#, fuzzy
-msgid "Detaching"
-msgstr "Wolumeny"
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-#, fuzzy
-msgid "Unable to retrieve volume details."
-msgstr "Nie można utworzyć wolumenu: %s"
-
-#: dashboards/project/volumes/views.py:49
-#, fuzzy
-msgid "Unable to retrieve volume list."
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/volumes/views.py:56
-#, fuzzy
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr "Nie można cofnąć: %s"
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-#, fuzzy
-msgid "Unable to retrieve volume information."
-msgstr "Nie można wyrejestrować obrazu: %s"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-#, fuzzy
-msgid "Attach To Instance"
-msgstr "Uruchom obraz"
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-#, fuzzy
-msgid "Attach Volume"
-msgstr "Dołącz wolumen"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-#, fuzzy
-msgid "Volume Quotas"
-msgstr "Wolumeny"
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-#, fuzzy
-msgid "Create Volume Snapshot"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-#, fuzzy
-msgid "Volume Overview"
-msgstr "Instancje"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-#, fuzzy
-msgid "Attachments"
-msgstr "Dołącz wolumen"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-#, fuzzy
-msgid "Not attached"
-msgstr "Dołącz wolumen"
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-#, fuzzy
-msgid "Create a Volume"
-msgstr "Utwórz nowy wolumen."
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-#, fuzzy
-msgid "From here you can modify dashboard settings for your user."
-msgstr "Tutaj można zarządzać użytkownikami i rolami."
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr ""
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr ""
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr ""
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr ""
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr ""
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-#, fuzzy
-msgid "Unable to retrieve usage information."
-msgstr "Nie można wyrejestrować obrazu: %s"
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-#, fuzzy
-msgid "Project Name"
-msgstr "Usuń projekt"
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/pt/LC_MESSAGES/django.mo b/openstack_dashboard/locale/pt/LC_MESSAGES/django.mo
deleted file mode 100644
index 4e220add..00000000
--- a/openstack_dashboard/locale/pt/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/pt/LC_MESSAGES/django.po b/openstack_dashboard/locale/pt/LC_MESSAGES/django.po
deleted file mode 100644
index 9cafc0dc..00000000
--- a/openstack_dashboard/locale/pt/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4710 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Nuno Esteves <nuno.esteves@artelecom.pt>, 2013
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: pt\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr ""
-
-#: settings.py:153
-msgid "Czech"
-msgstr ""
-
-#: settings.py:154
-msgid "English"
-msgstr "Inglês"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Espanhol"
-
-#: settings.py:156
-msgid "French"
-msgstr "Francês"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Italiano"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Japonês"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr ""
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr ""
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Polonês"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Português"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr ""
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Chinês Simplificado"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Chinês Tradicional"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr ""
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr ""
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr ""
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr ""
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr ""
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr ""
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "Redes"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr ""
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr ""
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr ""
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Projetos"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr ""
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr ""
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr ""
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr ""
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr ""
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Proibido"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Origem"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Página não Encontrada"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "A página que você estava procurando não existe"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "Você pode ter digitado incorretamente o endereço ou a página pode ter mudado."
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr ""
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.mo b/openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.mo
deleted file mode 100644
index 2eadaf24..00000000
--- a/openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.po b/openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.po
deleted file mode 100644
index bfe246cc..00000000
--- a/openstack_dashboard/locale/pt_BR/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4713 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# caiofelix <caio391@gmail.com>, 2013
-# openfly <matt@nycresistor.com>, 2013
-# pauloricardomg <pauloricardomg@gmail.com>, 2012
-# Rafael Ferreira <rafael.f.f1@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 22:24+0000\n"
-"Last-Translator: openfly <matt@nycresistor.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: pt_BR\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "Bulgário (Bulgária)"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "Tchecp"
-
-#: settings.py:154
-msgid "English"
-msgstr "Inglês"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Espanhol"
-
-#: settings.py:156
-msgid "French"
-msgstr "Francês"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Italiano"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Japonês"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "Coreano (Coreia)"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "Holandês (Holanda)"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Polonês"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Português"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "Português"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Chinês Simplificado"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Chinês Tradicional"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr ""
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr "Painel do Sistema"
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr "Administrador"
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr "Nome"
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr "VCPUs"
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr "RAM MB"
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr "Disco Root GB"
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr "Disco Temporário GB"
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr "Criado sabor \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr "Incapaz de criar sabor."
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr "Atualizado sabor \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr "Não foi possível atualizar o sabor."
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr "Sabors"
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr "Sabor"
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr "Criar Sabor"
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr "Editar Sabor"
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr "%sMB"
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr "Nome do Sabor"
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "RAM"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr "Disco Root"
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr "Disco Temporário"
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr "Não foi possível obter a lista de sabors."
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr "Não foi possível recuperar detalhes do sabor."
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr "Editar"
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "Descrição"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr "Aqui você pode definir o tamanho de um novo flavor."
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "Cancelar"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr "Aqui você pode definir o tamanho de um novo flavor."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr "Salvar"
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr "Imagems"
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr "Nome de Imagem"
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr "Não foi possível obter a lista de imagens."
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr "Descrição:"
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr "Criar Imagem"
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr "Atualizar Imagem."
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr "A partir daqui você pode modificar diferentes propriedades de uma imagem."
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr "Nome de Quota"
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr "Limite"
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr "Quotas"
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr "Id"
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr "Serviço"
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr "Servidor"
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr "Habilitado"
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr "Serviços"
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr "Quotas Padrão"
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr "Não foi possível obter informações de quota"
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr "Instâncias"
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr "Instância"
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "Projeto"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr "Endereço IP"
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr "Tamanho"
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr "Condição"
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr "Tarefa"
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr "Estado de energia"
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr "Não foi possível recuperar a lista de instâncias."
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr "Não foi possível obter informações sobre a instância de tenant"
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr "Não é possível recuperar informações de tamanho instância."
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr "Todas as Instâncias"
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr "Estado de Administração"
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr "Selecionar um projeto"
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr "Rede \"%s\" criada com sucesso."
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr "Falha ao criar rede %s"
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr "ID"
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr "Rede %s foi atualizado com sucesso."
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr "Falha ao atualizar rede %s"
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "Redes"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr "Rede"
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr "Falha ao apagar rede %s"
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr "Criar Rede"
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr "Editar Rede"
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "Nome de Rede"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr "Sub-redes Associadas"
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr "Lista de rede não pode ser recuperada."
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr "Lista de sub-rede não pode ser recuperada."
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr "Lista de portas não podem ser recuperadas."
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr "Não foi possível obter detalhes de rede \"%s\"."
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "Rede ID"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr "Dispositivo ID"
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr "Porta %s criada com sucesso."
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr "Falha ao criar uma porta para a rede %s"
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr "Porta %s atualizada com sucesso."
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr "Falha ao atualizar porta %s"
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "Porta"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "Portas"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr "Falha ao apagar rede %s"
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr "Criar Porta"
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr "Alterar Porta"
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr "IP Fixo"
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr "Visão Global"
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr "Não foi possível obter detalhes da porta."
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr "Não é possível recuperar redes."
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr "Sub-rede"
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr "Sub-redes"
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr "Criar sub-rede"
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr "Editar Sub-rede"
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr "CIDR"
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr "IP Versão"
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr "IP do Gateway"
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr "Falha ao recuperar rede %s para uma sub-rede"
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr "Selecione as nome para sua rede."
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr "Você pode atualizar as propriedades editáveis da sua rede aqui."
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr "Salvar Alterações"
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr "Você pode criar uma porta para a rede. Se você especificar ID do dispositivo a ser conectado, o dispositivo especificado será conectado à porta criado."
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr "Você pode atualizar as propriedades editáveis da sua porta aqui."
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr "Atualizar Porta"
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr "Detalhes de Rede"
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr "Atualizar Sub-rede"
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr "Resumo de utilização"
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr "Monitorando"
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Projetos"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr "Modificar usuários"
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr "Ver Uso"
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr "Criar Projeto"
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr "Editar Projeto"
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr "Projeto ID"
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr "Remover"
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr "Removido"
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr "Usuário"
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr "Usuários"
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr "Não é possível recuperar informações de função."
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr "Funções"
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr "Usuários por Projeto"
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr "Adicionar ao Porjeto"
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr "Adicionar Novos Usuários"
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr "Não é possível recuperar informações de projeto."
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr "Não foi possível obter a lista de projeto."
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr "Não foi possível obter os usuários."
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr "Não é possível recuperar valores de cota padrão."
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr "Não foi possível obter detalhes da projeto."
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr "Items de metadados"
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr "Arquivos injetados"
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr "Volumes"
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr "Gigabytes"
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr "RAM (MB)"
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr "IPs Flutuantes"
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr "Grupos de Segurança"
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr "Regras de Segurança do Grupo"
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr "Quota"
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr "Informação do Projeto"
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr "Aqui você pode criar um projeto para organizar usuários"
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr "Não foi possível obter a lista de usuários. Por favor tente novamente depois."
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr "Todos Usuários"
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr "Nenhum usuário encontrado."
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr "Não foi possível obter a lista de usuários."
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr "Criado novo projeto \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr "Incapaz de criar a projeto \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr "Aqui você pode editar a detalhes de o projeto."
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr "Projeto alterado \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr "Não foi possível alterar o projeto \"%s\"."
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr "Adicionar Usuário ao Projeto"
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr "Adicionar"
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr "Criar usuário para projeto '%(tenant_name)s'."
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr "Aqui você pode criar um novo usuário para adicionar neste projeto."
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr "Criar Usuário"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr "Atualizar Quota"
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr "Aqui você pode editar quotas (limites máx.) para o projeto %(tenant.name)s."
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr "Atualizar Projeto"
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr "Aqui você pode editar um projeto."
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr "Aqui você pode adicionar e remover membros deste projeto a partir da lista de usuários disponíveis."
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr "Adicionar Novo Usuário"
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr "Resumo de Utilização do Projeto"
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr "Utilização do Projeto"
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr "Usuários por Projeto"
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr "Tipo"
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr "As senhas não combinam."
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr "Nome do Usuário"
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr "Email"
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr "Senha"
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr "Confirme a Senha"
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr "Projeto Primário"
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr "Função"
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr "Usuário \"%s\" criado com sucesso."
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr "Não foi possível adicionar usuário ao projeto primário."
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr "Falha ao criar usuário."
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr "nome"
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr "email"
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr "projeto primário"
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr "senha"
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr "O usuário foi atualizado com sucesso."
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr "Não foi possível atualizar %(attributes)s para o usuário."
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr "Habilitar"
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr "Desabilitar"
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr "Desabilitado"
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr "Você não pode desabilitar o usuário que você está logado no momento."
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr "Usuário ID"
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr "Não foi possível atualizar o usuário."
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr "Não é possível recuperar as funções do usuário."
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr "Aqui você pode criar um novo usuário e associar ele a um projeto."
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr "Atualizar Usuário"
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr "Aqui você pode editar os detalhes de usuário, incluindo o projeto padrão dele."
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr "Detalhes do Volume"
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr "Detalhe do Volume"
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr "Administrar Computar"
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr "Armazenar o Objeto"
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr "Acesso e Segurança"
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr "Não é possível recuperar grupos de segurança"
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr "Par de chaves"
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr "Não foi possível recuperar a lista de par de chaves."
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr "Não foi possível obter o endereço IP flutuante."
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr "Não foi possível obter o endereço IP flutuante."
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr "Conjunto"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr "Alocados IP Flutuante %(ip)s"
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr "Incapaz de alocar IP flutuante."
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr "Alocar IP para Projeto"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr "Liberar"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr "Liberado"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr "IP Flutuante"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr "IP Flutuante associado"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr "Remover IP Flutuante"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr "Com sucesso dissociada IP flutuante: %s"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr "Não é possível associar IP flutuante"
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr "Conjunto Flutuante IP"
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr "Sem flutuantes conjuntos IP disponível."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr "Escolha o endereço IP que você deseja associar com a instância selecionada."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr "Selecione um endereço IP"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr "Nenhum endereço IP disponível"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr "Selecione uma instância"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr "Não há instâncias disponíveis"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr "Gerenciar Associações de IP Flutuante"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr "Associar"
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr "Endereço IP %s associado."
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr "Não é possível associar IP flutuante %s."
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr "Par de Chaves Nome"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr "Nomes par de chaves pode conter apenas letras, números, sublinhados e hífens."
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr "Chave Pública"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr "Importado com sucesso chave pública: %s"
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr "Não foi possível importar o par de chave."
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr "Par de chave"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr "Importar Par de Chaves"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr "Criar Par de Chaves"
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr "Impressão Digital"
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr "Não é possível criar par de chaves: %(exc)s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr "Criado Grupo de Segurança: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr "Não é possível criar grupo de segurança."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr "Protocolo IP"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr "O protocolo que essa regra deve ser aplicada."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr "A partir da porta"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr "Para portar"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr "Código"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr "Fonte"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr "Grupo de Segurança"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr "O tipo ICMP é inválido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr "O código ICMP é inválido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr "O tipo de ICMP não está no range (-1,255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr "O código de ICMP não está no range (-1,255)"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr "O número de porta \"de\" é inválido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr "O número de porta \"a\" é inválido."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr "O número de porta \"a\" tem de ser maior do que ou igual ao número de porta \"de\"."
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr "Regra adicionado com sucesso: %s"
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr "Criar Grupo de Segurança"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr "Editar Regrars"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr "Adicionar Regra"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr "Regra"
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr "Regras"
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr "Não é possível recuperar grupo de segurança"
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr "%s (atual)"
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr "Acesso e Segurança"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr "Alocar IP Flutuante"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr "Quotas de Projeto"
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr "Alocar IP"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr "Baixa par de chaves"
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr "A partir daqui você pode criar um novo grupo de segurança"
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr "Editar regras do Grupo de Segurança "
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr "Swift"
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr "Recipiente"
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr "Barra não é um caracter permitido."
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr "Nome do Recipiente"
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr "Recipiente criado com sucesso"
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr "Pasta criada com sucesso."
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr "Não é possível criar recipiente"
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr "Nome do Objeto"
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr "Arquivo"
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr "Objeto foi carregado com sucesso."
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr "Não é possível carregar objeto"
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr "Recipiente de destino"
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr "Nome do objeto de destino"
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr "Copiado \"%(orig)s\" a \"%(dest)s\" ao \"%(new)s\"."
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr "Não é possível copiar objeto."
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr "Recipientes"
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr "Criar Recipiente"
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr "Visualizar Container"
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr "Carregar Objeto"
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr "Objeto"
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr "Objectos"
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr "Copiar"
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr "Baixar"
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr "Não foi possível recuperar a lista de recipiente."
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr "Não foi possível recuperar a lista de objeto."
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr "Não foi possível recuperar o objeto."
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr "Impossível listar recipientes."
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr "Copiar Objeto"
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr "Faça uma nova cópia de um objeto existente para armazenar neste ou em outro recipiente. Você também pode especificar um caminho em que a nova cópia deve viver dentro do recipiente selecionado."
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr "Carregar Objetos"
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr "Imagens e Instantâneos"
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr "Não foi possível obter as imagems"
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr "Não é possível recuperar instantâneos."
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr "Não é possível recuperar instantâneos de volume."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr "Local da Imagem"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr "Formato"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr "AKI - Imagem de Kernel da Amazon"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr "AMI - Imagem de máquina Amazon"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr "ARI - Imagem de Ramdisk Amazon"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr "ISO - Imagem de disco óptico"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr "Disco Mínimo (GB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr "O tamanho mínimo em disco necessário para inicializar a imagem. Se não for especificado, este valor padrão é 0 (nenhum mínimo)."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr "Ram mínima (MB)"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr "Público"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr "Não foi possível criar a imagem novo."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr "Kernel ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr "Ramdisk ID"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr "Arquitetura"
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr "Não é possível atualizar imagem \"%s\"."
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr "A imagem foi atualizado com sucesso."
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr "Lançar"
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr "Imagem"
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr "Nome da instância"
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr "Endereço de Rede"
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr "Não foi possível obter detalhes da porta."
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr "Não foi possível obter detalhes da sub-rede."
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr "IP Versão"
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Proibido"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Página Inicial"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Página não encontrada"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "A página que procura não existe"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "Você pode ter digitado o endereço incorretamente ou a página pode ter se mudado."
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr "Nome de Projeto"
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/ru/LC_MESSAGES/django.mo b/openstack_dashboard/locale/ru/LC_MESSAGES/django.mo
deleted file mode 100644
index 9dc60c7d..00000000
--- a/openstack_dashboard/locale/ru/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/ru/LC_MESSAGES/django.po b/openstack_dashboard/locale/ru/LC_MESSAGES/django.po
deleted file mode 100644
index 1015fb0a..00000000
--- a/openstack_dashboard/locale/ru/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4712 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# adiantum <ilyaalekseyev@acm.org>, 2012
-# adiantum <ilyaalekseyev@acm.org>, 2013
-# Stanislav Hanzhin <hanzhin.stas@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-30 11:08+0000\n"
-"Last-Translator: adiantum <ilyaalekseyev@acm.org>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ru\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"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "Болгарский (Болгария)"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "Чешский"
-
-#: settings.py:154
-msgid "English"
-msgstr "Английский"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "Испанский"
-
-#: settings.py:156
-msgid "French"
-msgstr "Французский"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "Итальянский"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "Японский"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "Корейский (Корея)"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "Голландский (Нидерланды)"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "Польский"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "Португальский"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "Португальский"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "Упрощённый китайский"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "Традиционный китайский"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr "Неизвестный инстанс"
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr "Основной диск GB"
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr "Эфимерный диск GB"
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr "Создан тип сервера \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr "Невозможно создать тип сервера."
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr "Обновлен тип сервера \"%s\"."
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr "Невозможно обновить тип сервера."
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr "Типы серверов"
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr "Тип сервера"
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr "Создать тип сервера"
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr "Редактировать тип сервера"
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr "%sMB"
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr "Название типа сервера"
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr "RAM"
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr "Основной диск"
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr "Эфимерный диск"
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr "Невозможно получить список типов серверов."
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr "Невозможно получить данные типа сервера."
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr "Описание"
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr "Здесь вы можете определить объемы ресурсов нового типа сервера."
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr "Отменить"
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr "Здесь вы можете изменить объемы ресурсов текущего типа сервера."
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr ""
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr ""
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr "Проект"
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr ""
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr "Невозможно получить список инстансов."
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr ""
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr "Все инстансы"
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr "Выберите проект"
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr "Сеть %s была успешно создана."
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr "Не удалось создать сеть %s"
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr "Сеть %s была успешно обновлена."
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr "Не удалось обновить сеть %s"
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr "Сети"
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr "Сеть"
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr "Не удалось удалить сеть %s"
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr "Создать сеть"
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr "Редактировать сеть"
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr "Имя сети"
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr "Ассоциированные подсети"
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr "Не удается получить список сетей."
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr "Не удается получить список подсетей."
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr "Не удается получить список портов."
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr "Невозможно получить детальную информацию о сети \"%s\"."
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr "Идентификатор сети"
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr "Идентификатор устройства"
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr "Порт %s был успешно создан."
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr "Не удалось создать порт для сети %s"
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr "Порт %s был успешно обновлен."
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr "Не удалось обновить порт %s"
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr "Порт"
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr "Порты"
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr "Не удалось удалить подсеть %s"
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr "Создать порт"
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr "Редактировать порт"
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr "Фиксированные IP адреса"
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr "Устройство подключено"
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr "Обзор"
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr "Невозможно получить детальную информацию о порте."
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr ""
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "Проекты"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr ""
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr ""
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr ""
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr ""
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr ""
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "Запрещено"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "Домой"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "Страница не найдена"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "Страница, которую вы ищите, не существует"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "Ошибка в адресе страницы, или страница была перемещена."
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr ""
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.mo b/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.mo
deleted file mode 100644
index 8a0673c5..00000000
--- a/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.po b/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.po
deleted file mode 100644
index 085eb1e0..00000000
--- a/openstack_dashboard/locale/zh_CN/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4712 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# dangdang <11315889@qq.com>, 2012
-# daisy.ycguo <daisy.ycguo@gmail.com>, 2012
-# yuanke wei <weiyuanke123@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: English (http://www.transifex.com/projects/p/openstack/language/en/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_CN\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "保加利亚语(保加利亚)"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "捷克语"
-
-#: settings.py:154
-msgid "English"
-msgstr "英语"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "西班牙语"
-
-#: settings.py:156
-msgid "French"
-msgstr "法语"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "意大利语"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "日语"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "朝鲜语(韩语)"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "荷兰语 (荷兰)"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "波兰语"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "葡萄牙语"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "葡萄牙语"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "简体中文"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "繁体中文"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr ""
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr ""
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr ""
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr ""
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr ""
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr ""
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr ""
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr ""
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr ""
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "项目"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr ""
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr ""
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr ""
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr ""
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr ""
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "禁止"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "主页"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "页面未找到"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "你要找的页面不存在"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "你可能输入了错误的地址,或者该页面被删除了"
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr ""
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/locale/zh_TW/LC_MESSAGES/django.mo b/openstack_dashboard/locale/zh_TW/LC_MESSAGES/django.mo
deleted file mode 100644
index 030997c4..00000000
--- a/openstack_dashboard/locale/zh_TW/LC_MESSAGES/django.mo
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/locale/zh_TW/LC_MESSAGES/django.po b/openstack_dashboard/locale/zh_TW/LC_MESSAGES/django.po
deleted file mode 100644
index 264e94af..00000000
--- a/openstack_dashboard/locale/zh_TW/LC_MESSAGES/django.po
+++ /dev/null
@@ -1,4711 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-#
-# Translators:
-# Translators:
-# Translators:
-# Alberto Molina Coballes <alb.molina@gmail.com>, 2013
-# Chao-Hsiung Liao <pesder@gmail.com>, 2012
-msgid ""
-msgstr ""
-"Project-Id-Version: Horizon\n"
-"Report-Msgid-Bugs-To: https://launchpad.net/horizon\n"
-"POT-Creation-Date: 2013-03-12 04:09+0000\n"
-"PO-Revision-Date: 2013-04-29 08:35+0000\n"
-"Last-Translator: Gabriel Hurley <gabriel@strikeawe.com>\n"
-"Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/openstack/language/zh_TW/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_TW\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
-
-#: settings.py:152
-msgid "Bulgarian (Bulgaria)"
-msgstr "Búlgaro (Bulgaria)"
-
-#: settings.py:153
-msgid "Czech"
-msgstr "Checo"
-
-#: settings.py:154
-msgid "English"
-msgstr "英文"
-
-#: settings.py:155
-msgid "Spanish"
-msgstr "西班牙文"
-
-#: settings.py:156
-msgid "French"
-msgstr "法文"
-
-#: settings.py:157
-msgid "Italiano"
-msgstr "義大利文"
-
-#: settings.py:158
-msgid "Japanese"
-msgstr "日文"
-
-#: settings.py:159
-msgid "Korean (Korea)"
-msgstr "Coreano (Corea)"
-
-#: settings.py:160
-msgid "Dutch (Netherlands)"
-msgstr "Neerlandés (Holanda)"
-
-#: settings.py:161
-msgid "Polish"
-msgstr "波蘭文"
-
-#: settings.py:162
-msgid "Portuguese"
-msgstr "葡萄牙文"
-
-#: settings.py:163
-msgid "Portuguese (Brazil)"
-msgstr "Portugués"
-
-#: settings.py:164
-msgid "Simplified Chinese"
-msgstr "簡體中文"
-
-#: settings.py:165
-msgid "Traditional Chinese"
-msgstr "繁體中文"
-
-#: api/cinder.py:86
-msgid "Unknown instance"
-msgstr ""
-
-#: api/keystone.py:57
-#, python-format
-msgid "%(type)s (%(backend)s backend)"
-msgstr ""
-
-#: api/nova.py:171
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(group)s"
-msgstr ""
-
-#: api/nova.py:176
-#, python-format
-msgid "ALLOW %(from)s:%(to)s from %(cidr)s"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:24
-msgid "System Panel"
-msgstr ""
-
-#: dashboards/admin/dashboard.py:30
-msgid "Admin"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:36 dashboards/admin/info/tables.py:67
-#: dashboards/admin/instances/tables.py:91
-#: dashboards/admin/networks/forms.py:34 dashboards/admin/networks/forms.py:75
-#: dashboards/admin/networks/ports/forms.py:42
-#: dashboards/admin/networks/ports/tables.py:73
-#: dashboards/admin/networks/subnets/tables.py:70
-#: dashboards/admin/projects/tables.py:96
-#: dashboards/admin/projects/workflows.py:83
-#: dashboards/admin/routers/tables.py:63
-#: dashboards/admin/routers/ports/tables.py:43
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:7
-#: dashboards/admin/volumes/forms.py:31 dashboards/admin/volumes/tables.py:26
-#: dashboards/admin/volumes/tables.py:44
-#: dashboards/project/access_and_security/security_groups/forms.py:36
-#: dashboards/project/access_and_security/security_groups/tables.py:58
-#: dashboards/project/images_and_snapshots/images/forms.py:43
-#: dashboards/project/images_and_snapshots/images/forms.py:141
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:9
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:10
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:81
-#: dashboards/project/instances/templates/instances/_detail_overview.html:9
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:9
-#: dashboards/project/loadbalancers/tables.py:111
-#: dashboards/project/loadbalancers/workflows.py:34
-#: dashboards/project/loadbalancers/workflows.py:119
-#: dashboards/project/networks/forms.py:37
-#: dashboards/project/networks/tables.py:94
-#: dashboards/project/networks/ports/forms.py:36
-#: dashboards/project/networks/ports/tables.py:57
-#: dashboards/project/networks/subnets/tables.py:82
-#: dashboards/project/networks/templates/networks/_detail_overview.html:7
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:9
-#: dashboards/project/routers/tables.py:123
-#: dashboards/project/routers/ports/tables.py:75
-#: dashboards/project/routers/templates/routers/_detail_overview.html:7
-#: dashboards/project/volumes/tables.py:152
-#: dashboards/project/volumes/tables.py:172
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:9
-msgid "Name"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:37 dashboards/admin/flavors/tables.py:52
-#: dashboards/admin/projects/workflows.py:44
-#: dashboards/project/instances/templates/instances/_detail_overview.html:26
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:10
-#: usage/tables.py:19
-msgid "VCPUs"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:38
-msgid "RAM MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:39
-msgid "Root Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:40
-msgid "Ephemeral Disk GB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:41
-msgid "Swap Disk MB"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:49
-msgid "Unable to get flavor list"
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:56
-#, python-format
-msgid "The name \"%s\" is already used by another flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:70
-#, python-format
-msgid "Created flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:74
-msgid "Unable to create flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:106
-#, python-format
-msgid "Updated flavor \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/forms.py:110
-msgid "Unable to update flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/panel.py:29 dashboards/admin/flavors/tables.py:15
-#: dashboards/admin/flavors/tables.py:66
-#: dashboards/admin/flavors/templates/flavors/index.html:3
-#: dashboards/admin/flavors/templates/flavors/index.html:6
-msgid "Flavors"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:14
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:7
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:22
-#: dashboards/project/instances/workflows/create_instance.py:180
-msgid "Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:23
-#: dashboards/admin/flavors/templates/flavors/_create.html:8
-#: dashboards/admin/flavors/templates/flavors/_create.html:23
-#: dashboards/admin/flavors/templates/flavors/create.html:3
-#: dashboards/admin/flavors/templates/flavors/create.html:6
-msgid "Create Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:30
-#: dashboards/admin/flavors/templates/flavors/_edit.html:8
-#: dashboards/admin/flavors/templates/flavors/edit.html:3
-#: dashboards/admin/flavors/templates/flavors/edit.html:6
-msgid "Edit Flavor"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:37
-msgid "View Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:43 dashboards/admin/flavors/tables.py:47
-#, python-format
-msgid "%sMB"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:51
-msgid "Flavor Name"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:54
-#: dashboards/project/instances/templates/instances/_detail_overview.html:24
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: usage/tables.py:22
-msgid "RAM"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:56
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-msgid "Root Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:58
-#: dashboards/project/instances/templates/instances/_detail_overview.html:31
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-msgid "Ephemeral Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/tables.py:60
-msgid "Swap Disk"
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:49
-msgid "Unable to retrieve flavor list."
-msgstr ""
-
-#: dashboards/admin/flavors/views.py:76
-#: dashboards/admin/flavors/extras/views.py:45
-msgid "Unable to retrieve flavor data."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:34
-#: dashboards/admin/flavors/extras/forms.py:52
-#: dashboards/admin/flavors/extras/tables.py:61
-msgid "Key"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:35
-#: dashboards/admin/flavors/extras/forms.py:53
-#: dashboards/admin/flavors/extras/tables.py:62
-msgid "Value"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:43
-#, python-format
-msgid "Created extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:48
-msgid "Unable to create flavor extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:62
-#, python-format
-msgid "Saved extra spec \"%s\"."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/forms.py:66
-msgid "Unable to edit extra spec."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:31
-msgid "ExtraSpec"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:32
-msgid "ExtraSpecs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:41
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:24
-#: dashboards/project/networks/workflows.py:241
-#: dashboards/project/networks/subnets/workflows.py:61
-msgid "Create"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:51
-#: dashboards/admin/users/tables.py:30
-#: dashboards/project/images_and_snapshots/images/tables.py:71
-msgid "Edit"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/tables.py:66
-msgid "Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:61
-msgid "Unable to retrieve extra spec list."
-msgstr ""
-
-#: dashboards/admin/flavors/extras/views.py:90
-msgid "Unable to retrieve flavor extra spec data."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:17
-#: dashboards/admin/flavors/templates/flavors/_edit.html:17
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:18
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:18
-#: dashboards/admin/images/templates/images/_update.html:17
-#: dashboards/admin/networks/templates/networks/_create.html:17
-#: dashboards/admin/networks/templates/networks/ports/_create.html:17
-#: dashboards/admin/projects/tables.py:98
-#: dashboards/admin/projects/workflows.py:86
-#: dashboards/admin/projects/templates/projects/_add_user.html:17
-#: dashboards/admin/projects/templates/projects/_create.html:17
-#: dashboards/admin/projects/templates/projects/_create_user.html:17
-#: dashboards/admin/projects/templates/projects/_quotas.html:16
-#: dashboards/admin/projects/templates/projects/_update.html:17
-#: dashboards/admin/routers/templates/routers/ports/_create.html:17
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/admin/users/templates/users/_create.html:16
-#: dashboards/admin/users/templates/users/_update.html:16
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:17
-#: dashboards/project/access_and_security/security_groups/forms.py:42
-#: dashboards/project/access_and_security/security_groups/tables.py:59
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:16
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:17
-#: dashboards/project/containers/templates/containers/_copy.html:16
-#: dashboards/project/containers/templates/containers/_create.html:16
-#: dashboards/project/containers/templates/containers/_upload.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:15
-#: dashboards/project/loadbalancers/tables.py:113
-#: dashboards/project/loadbalancers/workflows.py:37
-#: dashboards/project/loadbalancers/workflows.py:122
-#: dashboards/project/networks/templates/networks/_create.html:16
-#: dashboards/project/routers/templates/routers/ports/_create.html:17
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:17
-#: dashboards/project/volumes/forms.py:30
-#: dashboards/project/volumes/forms.py:242
-#: dashboards/project/volumes/tables.py:155
-#: dashboards/project/volumes/templates/volumes/_create.html:18
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:17
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:14
-msgid "Description"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:18
-msgid "From here you can define the sizing of a new flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_create.html:24
-#: dashboards/admin/flavors/templates/flavors/_edit.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:25
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:25
-#: dashboards/admin/images/templates/images/_create.html:33
-#: dashboards/admin/images/templates/images/_update.html:24
-#: dashboards/admin/networks/templates/networks/_create.html:24
-#: dashboards/admin/networks/templates/networks/_update.html:23
-#: dashboards/admin/networks/templates/networks/ports/_create.html:24
-#: dashboards/admin/networks/templates/networks/ports/_update.html:28
-#: dashboards/admin/projects/templates/projects/_add_user.html:24
-#: dashboards/admin/projects/templates/projects/_create.html:24
-#: dashboards/admin/projects/templates/projects/_create_user.html:24
-#: dashboards/admin/projects/templates/projects/_quotas.html:23
-#: dashboards/admin/projects/templates/projects/_update.html:24
-#: dashboards/admin/routers/templates/routers/_create.html:20
-#: dashboards/admin/routers/templates/routers/ports/_create.html:24
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/admin/users/templates/users/_create.html:33
-#: dashboards/admin/users/templates/users/_update.html:33
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:28
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:32
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:24
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:27
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:24
-#: dashboards/project/containers/templates/containers/_copy.html:23
-#: dashboards/project/containers/templates/containers/_create.html:23
-#: dashboards/project/containers/templates/containers/_upload.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:33
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:24
-#: dashboards/project/networks/templates/networks/_create.html:23
-#: dashboards/project/networks/templates/networks/_update.html:23
-#: dashboards/project/networks/templates/networks/ports/_update.html:28
-#: dashboards/project/routers/templates/routers/_create.html:20
-#: dashboards/project/routers/templates/routers/ports/_create.html:24
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:24
-#: dashboards/project/volumes/templates/volumes/_attach.html:24
-#: dashboards/project/volumes/templates/volumes/_create.html:56
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:24
-#: dashboards/settings/user/templates/user/_settings.html:24
-msgid "Cancel"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:18
-msgid "From here you can alter the sizing of the current flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:19
-msgid ""
-"Note: this will not affect the resources allocated to any existing instances"
-" using this flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/_edit.html:24
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:24
-#: dashboards/admin/projects/workflows.py:294
-#: dashboards/project/instances/workflows/update_instance.py:162
-#: dashboards/settings/user/templates/user/_settings.html:23
-msgid "Save"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/create.html:4
-msgid "Create Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_create.html:19
-msgid "Create a new \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:9
-#: dashboards/admin/flavors/templates/flavors/extras/edit.html:4
-msgid "Edit Flavor Extra Spec"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_edit.html:19
-msgid "Update an \"extra spec\" key-value pair for a flavor."
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:5
-#: dashboards/admin/flavors/templates/flavors/extras/index.html:4
-msgid "Flavor Extra Specs"
-msgstr ""
-
-#: dashboards/admin/flavors/templates/flavors/extras/_index.html:12
-msgid "Close"
-msgstr ""
-
-#: dashboards/admin/images/panel.py:29 dashboards/admin/images/tables.py:49
-#: dashboards/admin/images/templates/images/index.html:3
-#: dashboards/admin/images/templates/images/index.html:6
-#: dashboards/project/images_and_snapshots/images/tables.py:50
-#: dashboards/project/images_and_snapshots/images/tables.py:190
-msgid "Images"
-msgstr ""
-
-#: dashboards/admin/images/tables.py:45
-#: dashboards/project/images_and_snapshots/images/tables.py:171
-#: dashboards/project/instances/templates/instances/_detail_overview.html:78
-msgid "Image Name"
-msgstr ""
-
-#: dashboards/admin/images/views.py:56
-msgid "Unable to retrieve image list."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:8
-#: dashboards/admin/images/templates/images/create.html:3
-#: dashboards/admin/images/templates/images/create.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/create.html:6
-msgid "Create An Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:17
-#: dashboards/admin/networks/templates/networks/_update.html:16
-#: dashboards/admin/networks/templates/networks/ports/_update.html:21
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:17
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:16
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:17
-#: dashboards/project/networks/templates/networks/_update.html:16
-#: dashboards/project/networks/templates/networks/ports/_update.html:21
-#: dashboards/settings/user/templates/user/_settings.html:17
-msgid "Description:"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:19
-msgid "Specify an image to upload to the Image Service."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:22
-msgid ""
-"Currently only images available via an HTTP URL are supported. The image "
-"location must be accessible to the Image Service. Compressed image binaries "
-"are supported (.zip and .tar.gz.)"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:25
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:25
-msgid "Please note: "
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:26
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:26
-msgid ""
-"The Image Location field MUST be a valid and direct URL to the image binary."
-" URLs that redirect or serve error pages will result in unusable images."
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_create.html:32
-#: dashboards/project/images_and_snapshots/images/tables.py:64
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_create.html:32
-msgid "Create Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:8
-#: dashboards/admin/images/templates/images/_update.html:23
-#: dashboards/admin/images/templates/images/update.html:4
-#: dashboards/admin/images/templates/images/update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:7
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:22
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/update.html:6
-msgid "Update Image"
-msgstr ""
-
-#: dashboards/admin/images/templates/images/_update.html:18
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_update.html:17
-msgid "From here you can modify different properties of an image."
-msgstr ""
-
-#: dashboards/admin/info/panel.py:29
-#: dashboards/admin/info/templates/info/index.html:3
-#: dashboards/admin/info/templates/info/index.html:6
-msgid "System Info"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:28
-msgid "Quota Name"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:29
-msgid "Limit"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:36
-msgid "Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:66
-msgid "Id"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:68
-#: dashboards/project/access_and_security/api_access/tables.py:54
-msgid "Service"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:69 dashboards/admin/instances/tables.py:87
-#: dashboards/admin/volumes/tables.py:28
-msgid "Host"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:71 dashboards/admin/projects/tables.py:100
-#: dashboards/admin/projects/workflows.py:88
-#: dashboards/admin/projects/workflows.py:275
-#: dashboards/admin/users/tables.py:41 dashboards/admin/users/tables.py:113
-msgid "Enabled"
-msgstr ""
-
-#: dashboards/admin/info/tables.py:76 dashboards/admin/info/tabs.py:50
-msgid "Services"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:30
-msgid "Default Quotas"
-msgstr ""
-
-#: dashboards/admin/info/tabs.py:44
-msgid "Unable to get quota info."
-msgstr ""
-
-#: dashboards/admin/instances/panel.py:29
-#: dashboards/admin/instances/tables.py:46
-#: dashboards/admin/instances/tables.py:115
-#: dashboards/admin/instances/templates/instances/index.html:3
-#: dashboards/admin/projects/workflows.py:45
-#: dashboards/project/instances/panel.py:25
-#: dashboards/project/instances/tables.py:74
-#: dashboards/project/instances/tables.py:89
-#: dashboards/project/instances/tables.py:115
-#: dashboards/project/instances/tables.py:144
-#: dashboards/project/instances/tables.py:470
-#: dashboards/project/instances/templates/instances/index.html:3
-#: dashboards/project/instances/templates/instances/index.html:6
-msgid "Instances"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:43
-msgid "Migrate"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:44
-msgid "Scheduled migration (pending confirmation) of"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:45
-#: dashboards/project/access_and_security/floating_ips/tables.py:117
-#: dashboards/project/access_and_security/floating_ips/workflows.py:38
-#: dashboards/project/instances/tables.py:73
-#: dashboards/project/instances/tables.py:88
-#: dashboards/project/instances/tables.py:114
-#: dashboards/project/instances/tables.py:143
-#: dashboards/project/volumes/tables.py:219
-msgid "Instance"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:80
-#: dashboards/admin/networks/forms.py:36
-#: dashboards/admin/networks/tables.py:67
-#: dashboards/admin/projects/tables.py:71 dashboards/admin/routers/forms.py:37
-#: dashboards/admin/routers/tables.py:61 dashboards/admin/volumes/tables.py:29
-#: dashboards/project/dashboard.py:43
-#: dashboards/project/instances/workflows/create_instance.py:41
-msgid "Project"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:92
-#: dashboards/project/access_and_security/floating_ips/tables.py:114
-#: dashboards/project/access_and_security/floating_ips/workflows.py:34
-#: dashboards/project/access_and_security/floating_ips/workflows.py:41
-#: dashboards/project/instances/tables.py:447
-#: dashboards/project/loadbalancers/tables.py:138
-msgid "IP Address"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:94
-#: dashboards/project/containers/tables.py:231
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:30
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:37
-#: dashboards/project/instances/tables.py:449
-#: dashboards/project/volumes/tables.py:158
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:26
-msgid "Size"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:99
-#: dashboards/admin/networks/tables.py:74
-#: dashboards/admin/networks/ports/tables.py:77
-#: dashboards/admin/routers/tables.py:67
-#: dashboards/admin/routers/ports/tables.py:47
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/images/tables.py:177
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:13
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:18
-#: dashboards/project/instances/tables.py:454
-#: dashboards/project/instances/templates/instances/_detail_overview.html:13
-#: dashboards/project/networks/tables.py:100
-#: dashboards/project/networks/ports/tables.py:61
-#: dashboards/project/networks/templates/networks/_detail_overview.html:13
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:31
-#: dashboards/project/routers/tables.py:127
-#: dashboards/project/routers/ports/tables.py:79
-#: dashboards/project/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/volumes/tables.py:162
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:17
-msgid "Status"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:104
-#: dashboards/project/instances/tables.py:459
-msgid "Task"
-msgstr ""
-
-#: dashboards/admin/instances/tables.py:111
-#: dashboards/project/instances/tables.py:466
-msgid "Power State"
-msgstr ""
-
-#: dashboards/admin/instances/views.py:55
-#: dashboards/project/access_and_security/tabs.py:97
-#: dashboards/project/access_and_security/floating_ips/workflows.py:86
-msgid "Unable to retrieve instance list."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:69
-#: dashboards/admin/networks/views.py:48
-msgid "Unable to retrieve instance tenant information."
-msgstr ""
-
-#: dashboards/admin/instances/views.py:86
-#: dashboards/project/instances/views.py:81
-msgid "Unable to retrieve instance size information."
-msgstr ""
-
-#: dashboards/admin/instances/templates/instances/index.html:6
-msgid "All Instances"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:37 dashboards/admin/networks/forms.py:80
-#: dashboards/admin/networks/tables.py:76
-#: dashboards/admin/networks/ports/forms.py:44
-#: dashboards/admin/networks/ports/tables.py:79
-#: dashboards/admin/routers/ports/tables.py:51
-#: dashboards/project/loadbalancers/workflows.py:41
-#: dashboards/project/loadbalancers/workflows.py:143
-#: dashboards/project/loadbalancers/workflows.py:258
-#: dashboards/project/loadbalancers/workflows.py:377
-#: dashboards/project/networks/forms.py:42
-#: dashboards/project/networks/tables.py:102
-#: dashboards/project/networks/workflows.py:42
-#: dashboards/project/networks/ports/forms.py:38
-#: dashboards/project/networks/ports/tables.py:63
-#: dashboards/project/networks/templates/networks/_detail_overview.html:15
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:33
-#: dashboards/project/routers/ports/tables.py:83
-msgid "Admin State"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:39 dashboards/admin/networks/forms.py:81
-#: dashboards/admin/networks/tables.py:72
-#: dashboards/project/networks/tables.py:98
-#: dashboards/project/networks/templates/networks/_detail_overview.html:17
-msgid "Shared"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:41 dashboards/admin/networks/forms.py:82
-#: dashboards/admin/routers/tables.py:70
-#: dashboards/project/networks/templates/networks/_detail_overview.html:19
-#: dashboards/project/routers/tables.py:130
-#: dashboards/project/routers/ports/forms.py:90
-msgid "External Network"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:50 dashboards/admin/routers/forms.py:42
-#: dashboards/admin/users/forms.py:42
-msgid "Select a project"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:64
-#, python-format
-msgid "Network %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:70
-#, python-format
-msgid "Failed to create network %s"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:77
-#: dashboards/admin/networks/templates/networks/ports/_update.html:12
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:9
-#: dashboards/admin/users/forms.py:114
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:12
-#: dashboards/project/instances/templates/instances/_detail_overview.html:11
-#: dashboards/project/loadbalancers/tables.py:154
-#: dashboards/project/networks/forms.py:39
-#: dashboards/project/networks/templates/networks/_detail_overview.html:9
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_update.html:12
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:11
-#: dashboards/project/routers/templates/routers/_detail_overview.html:9
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:11
-msgid "ID"
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:93
-#: dashboards/project/networks/forms.py:51
-#, python-format
-msgid "Network %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/forms.py:98
-#: dashboards/project/networks/forms.py:56
-#, python-format
-msgid "Failed to update network %s"
-msgstr ""
-
-#: dashboards/admin/networks/panel.py:25
-#: dashboards/admin/networks/tables.py:35
-#: dashboards/admin/networks/tables.py:80
-#: dashboards/admin/networks/templates/networks/index.html:3
-#: dashboards/admin/networks/templates/networks/index.html:6
-#: dashboards/project/instances/workflows/create_instance.py:418
-#: dashboards/project/networks/panel.py:25
-#: dashboards/project/networks/tables.py:44
-#: dashboards/project/networks/tables.py:106
-#: dashboards/project/networks/templates/networks/index.html:3
-#: dashboards/project/networks/templates/networks/index.html:6
-msgid "Networks"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:34
-#: dashboards/project/networks/tables.py:43
-#: dashboards/project/networks/templates/networks/subnets/index.html:3
-#: dashboards/project/networks/templates/networks/subnets/index.html:6
-msgid "Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:41
-#: dashboards/project/networks/tables.py:59
-#, python-format
-msgid "Failed to delete network %s"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:49
-#: dashboards/admin/networks/templates/networks/_create.html:8
-#: dashboards/admin/networks/templates/networks/_create.html:23
-#: dashboards/admin/networks/templates/networks/create.html:3
-#: dashboards/admin/networks/templates/networks/create.html:6
-#: dashboards/project/network_topology/templates/network_topology/index.html:27
-#: dashboards/project/networks/tables.py:67
-#: dashboards/project/networks/workflows.py:240
-#: dashboards/project/networks/templates/networks/_create.html:7
-#: dashboards/project/networks/templates/networks/_create.html:22
-#: dashboards/project/networks/templates/networks/create.html:3
-#: dashboards/project/networks/templates/networks/create.html:6
-msgid "Create Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:56
-#: dashboards/admin/networks/templates/networks/_update.html:7
-#: dashboards/project/networks/tables.py:74
-#: dashboards/project/networks/templates/networks/_update.html:7
-msgid "Edit Network"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:68
-#: dashboards/admin/networks/ports/forms.py:35
-#: dashboards/project/networks/workflows.py:38
-msgid "Network Name"
-msgstr ""
-
-#: dashboards/admin/networks/tables.py:71
-#: dashboards/project/networks/tables.py:97
-msgid "Subnets Associated"
-msgstr ""
-
-#: dashboards/admin/networks/views.py:60
-#: dashboards/project/networks/views.py:52
-msgid "Network list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:91
-#: dashboards/project/networks/views.py:110
-msgid "Subnet list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:103
-#: dashboards/project/networks/views.py:122
-#: dashboards/project/routers/views.py:137
-msgid "Port list can not be retrieved."
-msgstr ""
-
-#: dashboards/admin/networks/views.py:118
-#: dashboards/project/networks/views.py:135
-#: dashboards/project/networks/subnets/tables.py:96
-#, python-format
-msgid "Unable to retrieve details for network \"%s\"."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:38
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:14
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:14
-msgid "Network ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:46
-#: dashboards/admin/networks/ports/forms.py:78
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:38
-msgid "Device ID"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:49
-#: dashboards/admin/networks/ports/forms.py:81
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:37
-msgid "Device Owner"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:63
-#, python-format
-msgid "Port %s was successfully created."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:68
-#, python-format
-msgid "Failed to create a port for network %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:94
-#: dashboards/project/networks/ports/forms.py:47
-#, python-format
-msgid "Port %s was successfully updated."
-msgstr ""
-
-#: dashboards/admin/networks/ports/forms.py:99
-#: dashboards/project/networks/ports/forms.py:52
-#, python-format
-msgid "Failed to update port %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:34
-#: dashboards/project/access_and_security/security_groups/forms.py:73
-#: dashboards/project/access_and_security/security_groups/forms.py:82
-#: dashboards/project/access_and_security/security_groups/forms.py:89
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:6
-msgid "Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:35
-#: dashboards/admin/networks/ports/tables.py:83
-#: dashboards/project/networks/ports/tables.py:70
-msgid "Ports"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:41
-#: dashboards/admin/networks/subnets/tables.py:39
-#: dashboards/project/networks/subnets/tables.py:51
-#, python-format
-msgid "Failed to delete subnet %s"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:51
-#: dashboards/admin/networks/templates/networks/ports/_create.html:8
-#: dashboards/admin/networks/templates/networks/ports/_create.html:23
-#: dashboards/admin/networks/templates/networks/ports/create.html:3
-#: dashboards/admin/networks/templates/networks/ports/create.html:6
-msgid "Create Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:62
-#: dashboards/admin/networks/templates/networks/ports/_update.html:7
-#: dashboards/project/networks/ports/tables.py:46
-#: dashboards/project/networks/templates/networks/ports/_update.html:7
-msgid "Edit Port"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:75
-#: dashboards/admin/routers/ports/tables.py:45
-#: dashboards/project/networks/ports/tables.py:59
-#: dashboards/project/routers/ports/tables.py:77
-msgid "Fixed IPs"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tables.py:76
-#: dashboards/admin/routers/ports/tables.py:46
-#: dashboards/project/routers/ports/tables.py:78
-msgid "Device Attached"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:32
-#: dashboards/admin/overview/panel.py:29
-#: dashboards/admin/overview/templates/overview/usage.html:6
-#: dashboards/project/images_and_snapshots/images/tabs.py:27
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:27
-#: dashboards/project/instances/tabs.py:26
-#: dashboards/project/networks/ports/tabs.py:32
-#: dashboards/project/networks/subnets/tabs.py:32
-#: dashboards/project/overview/panel.py:29
-#: dashboards/project/overview/templates/overview/usage.html:6
-#: dashboards/project/routers/tabs.py:26
-#: dashboards/project/routers/ports/tabs.py:29
-#: dashboards/project/volumes/tabs.py:27
-msgid "Overview"
-msgstr ""
-
-#: dashboards/admin/networks/ports/tabs.py:42
-#: dashboards/project/networks/ports/tabs.py:42
-#: dashboards/project/routers/ports/tabs.py:40
-msgid "Unable to retrieve port details."
-msgstr ""
-
-#: dashboards/admin/networks/ports/views.py:53
-#: dashboards/project/networks/subnets/views.py:50
-msgid "Unable to retrieve network."
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:32
-#: dashboards/project/loadbalancers/tables.py:114
-#: dashboards/project/loadbalancers/workflows.py:38
-#: dashboards/project/networks/subnets/tables.py:44
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:6
-#: dashboards/project/routers/ports/forms.py:31
-msgid "Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:33
-#: dashboards/admin/networks/subnets/tables.py:81
-#: dashboards/project/networks/subnets/tables.py:45
-#: dashboards/project/networks/subnets/tables.py:104
-msgid "Subnets"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:49
-#: dashboards/admin/networks/templates/networks/subnets/create.html:3
-#: dashboards/admin/networks/templates/networks/subnets/create.html:6
-#: dashboards/project/networks/workflows.py:58
-#: dashboards/project/networks/subnets/tables.py:61
-#: dashboards/project/networks/subnets/workflows.py:60
-#: dashboards/project/networks/templates/networks/subnets/create.html:3
-#: dashboards/project/networks/templates/networks/subnets/create.html:6
-msgid "Create Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:60
-#: dashboards/project/networks/subnets/tables.py:72
-msgid "Edit Subnet"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:133
-#: dashboards/project/access_and_security/security_groups/forms.py:145
-#: dashboards/project/access_and_security/security_groups/forms.py:155
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:18
-msgid "CIDR"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:73
-#: dashboards/project/networks/workflows.py:73
-#: dashboards/project/networks/subnets/tables.py:85
-#: dashboards/project/networks/subnets/workflows.py:106
-msgid "IP Version"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/tables.py:74
-#: dashboards/project/networks/subnets/tables.py:86
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:29
-msgid "Gateway IP"
-msgstr ""
-
-#: dashboards/admin/networks/subnets/workflows.py:48
-#, python-format
-msgid "Failed to retrieve network %s for a subnet"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_create.html:18
-#: dashboards/project/networks/templates/networks/_create.html:17
-msgid "Select a name for your network."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:17
-#: dashboards/project/networks/templates/networks/_update.html:17
-msgid "You may update the editable properties of your network here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/_update.html:22
-#: dashboards/admin/networks/templates/networks/ports/_update.html:27
-#: dashboards/project/networks/templates/networks/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:27
-msgid "Save Changes"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/update.html:3
-#: dashboards/admin/networks/templates/networks/update.html:6
-#: dashboards/project/networks/templates/networks/update.html:3
-#: dashboards/project/networks/templates/networks/update.html:6
-msgid "Update Network"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_create.html:18
-msgid ""
-"You can create a port for the network. If you specify device ID to be "
-"attached, the device specified will be attached to the port created."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/_update.html:22
-#: dashboards/project/networks/templates/networks/ports/_update.html:22
-msgid "You may update the editable properties of your port here."
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/ports/update.html:3
-#: dashboards/admin/networks/templates/networks/ports/update.html:6
-#: dashboards/project/networks/templates/networks/ports/update.html:3
-#: dashboards/project/networks/templates/networks/ports/update.html:6
-msgid "Update Port"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/index.html:3
-#: dashboards/admin/networks/templates/networks/subnets/index.html:6
-#: dashboards/project/networks/templates/networks/detail.html:3
-msgid "Network Detail"
-msgstr ""
-
-#: dashboards/admin/networks/templates/networks/subnets/update.html:3
-#: dashboards/admin/networks/templates/networks/subnets/update.html:6
-#: dashboards/project/networks/subnets/workflows.py:154
-#: dashboards/project/networks/templates/networks/subnets/update.html:3
-#: dashboards/project/networks/templates/networks/subnets/update.html:6
-msgid "Update Subnet"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:3
-msgid "Usage Overview"
-msgstr ""
-
-#: dashboards/admin/overview/templates/overview/usage.html:12
-msgid "Monitoring"
-msgstr ""
-
-#: dashboards/admin/projects/panel.py:29
-#: dashboards/admin/projects/tables.py:72
-#: dashboards/admin/projects/tables.py:104
-#: dashboards/admin/projects/templates/projects/index.html:3
-#: dashboards/admin/projects/templates/projects/index.html:6
-#: templates/403.html:24 templates/404.html:23
-msgid "Projects"
-msgstr "專案"
-
-#: dashboards/admin/projects/tables.py:19
-msgid "Modify Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:32
-msgid "View Usage"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:39
-#: dashboards/admin/projects/workflows.py:201
-#: dashboards/admin/projects/workflows.py:202
-#: dashboards/admin/projects/templates/projects/_create.html:8
-#: dashboards/admin/projects/templates/projects/_create.html:23
-#: dashboards/admin/projects/templates/projects/create.html:3
-#: dashboards/admin/projects/templates/projects/create.html:6
-msgid "Create Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:49
-#: dashboards/admin/projects/workflows.py:293
-#: dashboards/admin/projects/templates/projects/update.html:3
-#: dashboards/admin/projects/templates/projects/update.html:6
-msgid "Edit Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:99
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:11
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:60
-#: dashboards/project/networks/templates/networks/_detail_overview.html:11
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:16
-msgid "Project ID"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:113
-msgid "Remove"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:114
-msgid "Removed"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:115 dashboards/admin/users/tables.py:42
-#: dashboards/admin/users/tables.py:79
-#: dashboards/project/instances/workflows/create_instance.py:42
-msgid "User"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:116 dashboards/admin/users/panel.py:29
-#: dashboards/admin/users/tables.py:43 dashboards/admin/users/tables.py:80
-#: dashboards/admin/users/tables.py:120
-#: dashboards/admin/users/templates/users/index.html:3
-#: dashboards/admin/users/templates/users/index.html:6
-msgid "Users"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:134
-msgid "Unable to retrieve role information."
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:139
-msgid "Roles"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:143
-msgid "Users For Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:151
-msgid "Add To Project"
-msgstr ""
-
-#: dashboards/admin/projects/tables.py:163
-msgid "Add New Users"
-msgstr ""
-
-#: dashboards/admin/projects/views.py:70
-msgid "Unable to retrieve project information."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:90
-msgid "Unable to retrieve project list."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:113
-msgid "Unable to retrieve users."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:156
-msgid "Unable to retrieve default quota values."
-msgstr ""
-
-#: dashboards/admin/projects/views.py:185
-msgid "Unable to retrieve project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:41
-msgid "Injected File Content Bytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:43
-msgid "Metadata Items"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:47
-msgid "Injected Files"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:50
-#: dashboards/admin/volumes/panel.py:9 dashboards/admin/volumes/tables.py:33
-#: dashboards/admin/volumes/templates/volumes/index.html:3
-#: dashboards/admin/volumes/templates/volumes/index.html:6
-#: dashboards/project/volumes/panel.py:25
-#: dashboards/project/volumes/tables.py:39
-#: dashboards/project/volumes/tables.py:182
-#: dashboards/project/volumes/tables.py:194
-#: dashboards/project/volumes/templates/volumes/index.html:3
-#: dashboards/project/volumes/templates/volumes/index.html:6
-msgid "Volumes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:51
-msgid "Gigabytes"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:52
-msgid "RAM (MB)"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:53
-#: dashboards/project/access_and_security/tabs.py:72
-#: dashboards/project/access_and_security/floating_ips/tables.py:52
-#: dashboards/project/access_and_security/floating_ips/tables.py:131
-msgid "Floating IPs"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:55
-#: dashboards/project/access_and_security/tabs.py:40
-#: dashboards/project/access_and_security/security_groups/tables.py:32
-#: dashboards/project/access_and_security/security_groups/tables.py:66
-#: dashboards/project/instances/templates/instances/_detail_overview.html:53
-#: dashboards/project/instances/workflows/create_instance.py:344
-#: dashboards/project/instances/workflows/update_instance.py:111
-msgid "Security Groups"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:57
-#: dashboards/project/access_and_security/security_groups/tables.py:119
-msgid "Security Group Rules"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:60
-msgid "Quota"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:62
-msgid "From here you can set quotas (max limits) for the project."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:93
-#: dashboards/admin/projects/workflows.py:278
-msgid "Project Info"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:94
-#: dashboards/admin/projects/templates/projects/_create.html:18
-msgid "From here you can create a new project to organize users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:113
-msgid "Unable to retrieve user list. Please try again later."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:125
-#, python-format
-msgid "Could not find default role \"%s\" in Keystone"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:173
-#: dashboards/admin/projects/workflows.py:180
-#: dashboards/admin/projects/templates/projects/_update_members.html:16
-msgid "Project Members"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:179
-#: dashboards/admin/projects/templates/projects/_update_members.html:10
-msgid "All Users"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:181
-#: dashboards/admin/projects/templates/projects/_update_members.html:25
-#: dashboards/admin/projects/templates/projects/_update_members.html:32
-msgid "No users found."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:182
-msgid "No users."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:190
-#: dashboards/admin/users/views.py:47
-msgid "Unable to retrieve user list."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:203
-#, python-format
-msgid "Created new project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:204
-#, python-format
-msgid "Unable to create project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:248
-#, python-format
-msgid "Failed to add %s project members and set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:270
-msgid "Unable to set project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:280
-msgid "From here you can edit the project details."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:295
-#, python-format
-msgid "Modified project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:296
-#, python-format
-msgid "Unable to modify project \"%s\"."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:349
-msgid ""
-"You cannot remove the \"admin\" role from the project you are currently "
-"logged into. Please switch to another project with admin permissions or "
-"remove the role manually via the CLI"
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:381
-#, python-format
-msgid "Failed to modify %s project members and update project quotas."
-msgstr ""
-
-#: dashboards/admin/projects/workflows.py:414
-msgid ""
-"Modified project information and members, but unable to modify project "
-"quotas."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:8
-#: dashboards/admin/projects/templates/projects/add_user.html:3
-#: dashboards/admin/projects/templates/projects/add_user.html:6
-msgid "Add User To Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:18
-msgid "Select the user role for the project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_add_user.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:26
-#: dashboards/project/loadbalancers/workflows.py:97
-#: dashboards/project/loadbalancers/workflows.py:194
-#: dashboards/project/loadbalancers/workflows.py:326
-#: dashboards/project/loadbalancers/workflows.py:430
-msgid "Add"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:7
-#, python-format
-msgid "Create User for project '%(tenant_name)s'."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:18
-msgid "From here you can create a new user to add to this project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_create_user.html:23
-#: dashboards/admin/users/tables.py:20
-#: dashboards/admin/users/templates/users/_create.html:7
-#: dashboards/admin/users/templates/users/_create.html:32
-#: dashboards/admin/users/templates/users/create.html:3
-#: dashboards/admin/users/templates/users/create.html:7
-msgid "Create User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:7
-#: dashboards/admin/projects/templates/projects/_quotas.html:22
-msgid "Update Quota"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_quotas.html:17
-#, python-format
-msgid ""
-"From here you can edit quotas (max limits) for the project %(tenant.name)s."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:8
-#: dashboards/admin/projects/templates/projects/_update.html:23
-#: dashboards/admin/projects/templates/projects/quotas.html:6
-msgid "Update Project"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update.html:18
-msgid "From here you can edit a project."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/_update_members.html:7
-msgid ""
-"From here you can add and remove members to this project from the list of "
-"all available users."
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/create_user.html:3
-#: dashboards/admin/projects/templates/projects/create_user.html:6
-msgid "Add New User"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/quotas.html:3
-msgid "Modify Project Quotas"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:3
-msgid "Project Usage Overview"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/usage.html:7
-msgid "Project Usage"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:3
-msgid "Project Users"
-msgstr ""
-
-#: dashboards/admin/projects/templates/projects/users.html:7
-msgid "Users for Project"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:35 dashboards/project/routers/forms.py:23
-#: dashboards/project/routers/ports/forms.py:32
-#: dashboards/project/routers/ports/forms.py:91
-msgid "Router Name"
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:48
-msgid "Failed to get tenants."
-msgstr ""
-
-#: dashboards/admin/routers/forms.py:67 dashboards/project/routers/forms.py:37
-#, python-format
-msgid "Failed to create router \"%s\"."
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:39
-#: dashboards/admin/routers/templates/routers/create.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:28
-#: dashboards/project/routers/tables.py:59
-#: dashboards/project/routers/templates/routers/create.html:3
-msgid "Create Router"
-msgstr ""
-
-#: dashboards/admin/routers/tables.py:77
-#: dashboards/admin/routers/templates/routers/index.html:3
-#: dashboards/admin/routers/templates/routers/index.html:6
-#: dashboards/project/routers/tables.py:34
-#: dashboards/project/routers/tables.py:137
-#: dashboards/project/routers/templates/routers/index.html:3
-#: dashboards/project/routers/templates/routers/index.html:6
-msgid "Routers"
-msgstr ""
-
-#: dashboards/admin/routers/views.py:51 dashboards/project/routers/views.py:55
-msgid "Unable to retrieve router list."
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:49
-#: dashboards/project/access_and_security/security_groups/forms.py:112
-#: dashboards/project/access_and_security/security_groups/forms.py:119
-#: dashboards/project/images_and_snapshots/images/tables.py:173
-#: dashboards/project/loadbalancers/workflows.py:365
-#: dashboards/project/routers/ports/tables.py:81
-#: dashboards/project/volumes/forms.py:31
-#: dashboards/project/volumes/tables.py:175
-msgid "Type"
-msgstr ""
-
-#: dashboards/admin/routers/ports/tables.py:58
-#: dashboards/project/routers/ports/tables.py:51
-#: dashboards/project/routers/ports/tables.py:90
-msgid "Interfaces"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_create.html:8
-#: dashboards/admin/routers/templates/routers/_create.html:19
-#: dashboards/project/routers/templates/routers/_create.html:8
-#: dashboards/project/routers/templates/routers/_create.html:19
-msgid "Create router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:3
-#: dashboards/project/routers/templates/routers/_detail_overview.html:3
-msgid "Router Overview"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:16
-#: dashboards/project/routers/templates/routers/_detail_overview.html:14
-msgid "External Gateway Information"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/_detail_overview.html:17
-#: dashboards/project/routers/templates/routers/_detail_overview.html:15
-msgid "Connected External Network"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/create.html:6
-#: dashboards/project/routers/templates/routers/create.html:6
-msgid "Create a Router"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:3
-#: dashboards/project/routers/templates/routers/detail.html:3
-msgid "Router Details"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/detail.html:6
-#: dashboards/project/routers/templates/routers/detail.html:6
-msgid "Router Detail"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:8
-#: dashboards/admin/routers/templates/routers/ports/create.html:3
-#: dashboards/admin/routers/templates/routers/ports/create.html:6
-#: dashboards/project/routers/ports/tables.py:40
-#: dashboards/project/routers/templates/routers/ports/_create.html:8
-#: dashboards/project/routers/templates/routers/ports/create.html:3
-#: dashboards/project/routers/templates/routers/ports/create.html:6
-msgid "Add Interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:18
-#: dashboards/project/routers/templates/routers/ports/_create.html:18
-msgid "You can connect a specified subnet to the router."
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_create.html:23
-#: dashboards/project/routers/templates/routers/ports/_create.html:23
-msgid "Add interface"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/admin/routers/templates/routers/ports/setgateway.html:6
-#: dashboards/project/routers/tables.py:66
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:8
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:23
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:3
-#: dashboards/project/routers/templates/routers/ports/setgateway.html:6
-msgid "Set Gateway"
-msgstr ""
-
-#: dashboards/admin/routers/templates/routers/ports/_setgateway.html:18
-#: dashboards/project/routers/templates/routers/ports/_setgateway.html:18
-msgid ""
-"You can connect a specified external network to the router. The external "
-"network is regarded as a default route of the router and the router acts as "
-"a gateway for external connectivity."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:54
-msgid "Passwords do not match."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:62 dashboards/admin/users/forms.py:115
-#: dashboards/admin/users/tables.py:106
-msgid "User Name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:63 dashboards/admin/users/forms.py:116
-#: dashboards/admin/users/tables.py:107
-msgid "Email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:65 dashboards/admin/users/forms.py:117
-msgid "Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:70 dashboards/admin/users/forms.py:124
-msgid "Confirm Password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:73 dashboards/admin/users/forms.py:127
-msgid "Primary Project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:75
-msgid "Role"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:96
-#, python-format
-msgid "User \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:106
-msgid "Unable to add userto primary project."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:110
-msgid "Unable to create user."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "name"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:151
-msgid "email"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:160
-msgid "primary project"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:173
-#, python-format
-msgid "The user %s has no role defined for"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:181
-msgid "password"
-msgstr ""
-
-#: dashboards/admin/users/forms.py:190
-msgid "User has been updated successfully."
-msgstr ""
-
-#: dashboards/admin/users/forms.py:194
-#, python-format
-msgid "Unable to update %(attributes)s for the user."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Enable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:40
-msgid "Disable"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:41
-msgid "Disabled"
-msgstr ""
-
-#: dashboards/admin/users/tables.py:67
-msgid "You cannot disable the user you are currently logged in as."
-msgstr ""
-
-#: dashboards/admin/users/tables.py:112
-msgid "User ID"
-msgstr ""
-
-#: dashboards/admin/users/views.py:70
-msgid "Unable to update user."
-msgstr ""
-
-#: dashboards/admin/users/views.py:104
-msgid "Unable to retrieve user roles."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_create.html:17
-msgid "From here you can create a new user and assign them to a project."
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:7
-#: dashboards/admin/users/templates/users/_update.html:32
-#: dashboards/admin/users/templates/users/update.html:3
-#: dashboards/admin/users/templates/users/update.html:7
-msgid "Update User"
-msgstr ""
-
-#: dashboards/admin/users/templates/users/_update.html:17
-msgid ""
-"From here you can edit the user's details, including their default project."
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:38
-#, python-format
-msgid "Successfully created volume type: %s"
-msgstr ""
-
-#: dashboards/admin/volumes/forms.py:43
-msgid "Unable to create volume type."
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:11
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:8
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:27
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:3
-msgid "Create Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:17
-msgid "Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/tables.py:18 dashboards/admin/volumes/tables.py:54
-msgid "Volume Types"
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:51
-msgid "Unable to retrieve volume tenant information."
-msgstr ""
-
-#: dashboards/admin/volumes/views.py:68
-msgid "Unable to retrieve volume types"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/_create_volume_type.html:18
-msgid ""
-"\n"
-" The volume type defines the characteristics of a volume.\n"
-" It usually maps to a set of capabilities of the storage back-end driver to be used for this volume.\n"
-" Examples: \"Performance\", \"SSD\", \"Backup\", etc.\n"
-" "
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/create_volume_type.html:6
-msgid "Create a Volume Type"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:3
-#: dashboards/project/volumes/templates/volumes/detail.html:3
-msgid "Volume Details"
-msgstr ""
-
-#: dashboards/admin/volumes/templates/volumes/detail.html:6
-#: dashboards/project/volumes/templates/volumes/detail.html:6
-msgid "Volume Detail"
-msgstr ""
-
-#: dashboards/project/dashboard.py:24
-msgid "Manage Compute"
-msgstr ""
-
-#: dashboards/project/dashboard.py:38
-msgid "Object Store"
-msgstr ""
-
-#: dashboards/project/access_and_security/panel.py:26
-#: dashboards/project/instances/workflows/create_instance.py:352
-msgid "Access & Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:50
-#: dashboards/project/access_and_security/security_groups/views.py:85
-msgid "Unable to retrieve security groups."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:56
-#: dashboards/project/access_and_security/keypairs/tables.py:31
-#: dashboards/project/access_and_security/keypairs/tables.py:60
-msgid "Keypairs"
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:66
-msgid "Unable to retrieve keypair list."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:82
-#: dashboards/project/access_and_security/floating_ips/workflows.py:70
-msgid "Unable to retrieve floating IP addresses."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:89
-#: dashboards/project/access_and_security/floating_ips/views.py:66
-msgid "Unable to retrieve floating IP pools."
-msgstr ""
-
-#: dashboards/project/access_and_security/tabs.py:111
-msgid "API Access"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:38
-#: dashboards/project/access_and_security/api_access/tables.py:39
-msgid "Download EC2 Credentials"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:46
-#: dashboards/project/access_and_security/api_access/tables.py:47
-msgid "Download OpenStack RC File"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:57
-msgid "Service Endpoint"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/tables.py:61
-msgid "API Endpoints"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:57
-msgid "Unable to fetch EC2 credentials."
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:93
-#, python-format
-msgid "Error writing zipfile: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/api_access/views.py:134
-#, python-format
-msgid "Error Downloading RC File: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:32
-#: dashboards/project/loadbalancers/tables.py:84
-#: dashboards/project/loadbalancers/tables.py:143
-#: dashboards/project/loadbalancers/workflows.py:249
-#: dashboards/project/loadbalancers/workflows.py:364
-msgid "Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:44
-#, python-format
-msgid "Allocated Floating IP %(ip)s."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/forms.py:48
-msgid "Unable to allocate Floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:39
-msgid "Allocate IP To Project"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:49
-msgid "Release"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:50
-msgid "Released"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:51
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:22
-msgid "Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:61
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/associate.html:6
-#: dashboards/project/instances/tables.py:299
-#: dashboards/project/instances/tables.py:320
-msgid "Associate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:78
-#: dashboards/project/instances/tables.py:344
-msgid "Disassociate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:93
-#, python-format
-msgid "Successfully disassociated Floating IP: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:97
-#: dashboards/project/instances/tables.py:370
-msgid "Unable to disassociate floating IP."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/tables.py:120
-msgid "Floating IP Pool"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/views.py:69
-msgid "No floating IP pools available."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:42
-msgid ""
-"Select the IP address you wish to associate with the selected instance."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:48
-msgid "Port to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:50
-msgid "Instance to be associated"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:74
-msgid "Select an IP address"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:76
-msgid "No IP addresses available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:98
-msgid "Select a port"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:100
-#: dashboards/project/volumes/forms.py:204
-msgid "Select an instance"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:104
-msgid "No ports available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:106
-#: dashboards/project/volumes/forms.py:206
-msgid "No instances available"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:126
-msgid "Manage Floating IP Associations"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:127
-msgid "Associate"
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:128
-#, python-format
-msgid "IP address %s associated."
-msgstr ""
-
-#: dashboards/project/access_and_security/floating_ips/workflows.py:129
-#, python-format
-msgid "Unable to associate IP address %s."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:38
-#: dashboards/project/access_and_security/keypairs/forms.py:49
-#: dashboards/project/access_and_security/keypairs/tables.py:52
-msgid "Keypair Name"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:40
-msgid ""
-"Keypair names may only contain letters, numbers, underscores and hyphens."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:51
-msgid "Public Key"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:60
-#, python-format
-msgid "Successfully imported public key: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/forms.py:65
-msgid "Unable to import keypair."
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:30
-#: dashboards/project/instances/tables.py:451
-#: dashboards/project/instances/workflows/create_instance.py:339
-msgid "Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:39
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/import.html:6
-msgid "Import Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:46
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/create.html:6
-msgid "Create Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/tables.py:53
-msgid "Fingerprint"
-msgstr ""
-
-#: dashboards/project/access_and_security/keypairs/views.py:74
-#, python-format
-msgid "Unable to create keypair: %(exc)s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:38
-msgid "This field is required."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:39
-msgid "The string may only contain ASCII characters and numbers."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:50
-#, python-format
-msgid "Successfully created security group: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:56
-msgid "Unable to create security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:62
-#: dashboards/project/access_and_security/security_groups/tables.py:105
-msgid "IP Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:63
-msgid "TCP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:64
-msgid "UDP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:65
-msgid "ICMP"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:66
-msgid "The protocol which this rule should be applied to."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:72
-#: dashboards/project/access_and_security/security_groups/forms.py:79
-#: dashboards/project/access_and_security/security_groups/forms.py:80
-msgid "Open"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:74
-msgid "Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:84
-#: dashboards/project/access_and_security/security_groups/forms.py:94
-#: dashboards/project/access_and_security/security_groups/forms.py:104
-msgid "Enter an integer value between 1 and 65535."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:92
-#: dashboards/project/access_and_security/security_groups/forms.py:99
-#: dashboards/project/access_and_security/security_groups/tables.py:107
-msgid "From Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:102
-#: dashboards/project/access_and_security/security_groups/forms.py:109
-#: dashboards/project/access_and_security/security_groups/tables.py:108
-msgid "To Port"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:114
-msgid "Enter a value for ICMP type in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:122
-#: dashboards/project/access_and_security/security_groups/forms.py:129
-msgid "Code"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:124
-msgid "Enter a value for ICMP code in the range (-1: 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:132
-#: dashboards/project/access_and_security/security_groups/tables.py:109
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid "Source"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:134
-#: dashboards/project/access_and_security/security_groups/forms.py:157
-#: dashboards/project/access_and_security/security_groups/forms.py:162
-#: dashboards/project/access_and_security/security_groups/tables.py:31
-msgid "Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:135
-msgid ""
-"To specify an allowed IP range, select \"CIDR\". To allow access from all "
-"members of another security group select \"Security Group\"."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:148
-msgid "Classless Inter-Domain Routing (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:173
-msgid "No security groups available"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:192
-msgid "The ICMP type is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:195
-msgid "The ICMP code is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:198
-msgid "The ICMP type not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:201
-msgid "The ICMP code not in range (-1, 255)"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:210
-msgid "The specified port is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:214
-msgid "The \"from\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:217
-msgid "The \"to\" port number is invalid."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:220
-msgid ""
-"The \"to\" port number must be greater than or equal to the \"from\" port "
-"number."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:242
-#, python-format
-msgid "Successfully added rule: %s"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/forms.py:248
-msgid "Unable to add rule to security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:45
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:23
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/create.html:6
-msgid "Create Security Group"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:52
-msgid "Edit Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:73
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:7
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/add_rule.html:6
-msgid "Add Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:82
-msgid "Rule"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/tables.py:83
-msgid "Rules"
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:55
-msgid "Unable to retrieve security group."
-msgstr ""
-
-#: dashboards/project/access_and_security/security_groups/views.py:91
-#, python-format
-msgid "%s (current)"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/index.html:6
-msgid "Access &amp; Security"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:8
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/allocate.html:3
-msgid "Allocate Floating IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:18
-msgid "Allocate a floating IP from a given floating ip pool."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:20
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:19
-msgid "Project Quotas"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/floating_ips/_allocate.html:31
-msgid "Allocate IP"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:17
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:17
-msgid ""
-"Keypairs are ssh credentials which are injected into images when they are "
-"launched. Creating a new key pair registers the public key and downloads the"
-" private key (a .pem file)."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_create.html:18
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/_import.html:18
-msgid "Protect and use the key as you would any normal ssh private key."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:6
-msgid "Download Keypair"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:11
-#, python-format
-msgid ""
-"The keypair &quot;%(keypair_name)s&quot; should download automatically. If "
-"not use the link below."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/keypairs/download.html:15
-#, python-format
-msgid "Download keypair &quot;%(keypair_name)s&quot;"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:18
-msgid ""
-"Rules define which traffic is allowed to instances assigned to the security "
-"group. A security group rule consists of three main parts:"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-#: dashboards/project/loadbalancers/tables.py:115
-#: dashboards/project/loadbalancers/workflows.py:39
-#: dashboards/project/loadbalancers/workflows.py:132
-msgid "Protocol"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:19
-msgid ""
-"You must specify the desired IP protocol to which this rule will apply; the "
-"options are TCP, UDP, or ICMP."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid "Open Port/Port Range"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:20
-msgid ""
-"For TCP and UDP rules you may choose to open either a single port or a range"
-" of ports. Selecting the \"Port Range\" option will provide you with space "
-"to provide both the starting and ending ports for the range. For ICMP rules "
-"you instead specify an ICMP type and code in the spaces provided."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_add_rule.html:21
-msgid ""
-"You must specify the source of the traffic to be allowed via this rule. You "
-"may do so either in the form of an IP address block (CIDR) or via a source "
-"group (Security Group). Selecting a security group as the source will allow "
-"any other instance in that security group access to any other instance via "
-"this rule."
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/_create.html:18
-msgid "From here you can create a new security group"
-msgstr ""
-
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:3
-#: dashboards/project/access_and_security/templates/access_and_security/security_groups/detail.html:6
-msgid "Edit Security Group Rules"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:26
-msgid "Swift"
-msgstr ""
-
-#: dashboards/project/containers/browsers.py:29
-#: dashboards/project/containers/tables.py:40
-msgid "Container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:39
-msgid "Slash is not an allowed character."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:49
-#: dashboards/project/containers/tables.py:121
-msgid "Container Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:57
-msgid "Container created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:68
-msgid "Folder created successfully."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:71
-msgid "Unable to create container."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:79
-#: dashboards/project/containers/tables.py:228
-msgid "Object Name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:80
-msgid ""
-"Slashes are allowed, and are treated as pseudo-folders by the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:83
-msgid "File"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:97
-msgid "Object was successfully uploaded."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:100
-msgid "Unable to upload object."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:104
-msgid "Destination container"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:108
-msgid "Destination object name"
-msgstr ""
-
-#: dashboards/project/containers/forms.py:141
-#, python-format
-msgid "Copied \"%(orig)s\" to \"%(dest)s\" as \"%(new)s\"."
-msgstr ""
-
-#: dashboards/project/containers/forms.py:151
-msgid "Unable to copy object."
-msgstr ""
-
-#: dashboards/project/containers/panel.py:29
-#: dashboards/project/containers/tables.py:41
-#: dashboards/project/containers/tables.py:128
-#: dashboards/project/containers/templates/containers/index.html:3
-#: dashboards/project/containers/templates/containers/index.html:7
-msgid "Containers"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:62
-#: dashboards/project/containers/templates/containers/_create.html:7
-#: dashboards/project/containers/templates/containers/_create.html:22
-#: dashboards/project/containers/templates/containers/create.html:3
-#: dashboards/project/containers/templates/containers/create.html:6
-msgid "Create Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:69
-msgid "View Container"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:81
-#: dashboards/project/containers/templates/containers/_upload.html:24
-#: dashboards/project/containers/templates/containers/upload.html:3
-msgid "Upload Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:137
-#: dashboards/project/containers/tables.py:149
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid "Object"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:138
-#: dashboards/project/containers/tables.py:150
-#: dashboards/project/containers/tables.py:235
-msgid "Objects"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:156
-msgid "Copy"
-msgstr ""
-
-#: dashboards/project/containers/tables.py:169
-msgid "Download"
-msgstr ""
-
-#: dashboards/project/containers/views.py:53
-msgid "Unable to retrieve container list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:83
-msgid "Unable to retrieve object list."
-msgstr ""
-
-#: dashboards/project/containers/views.py:168
-msgid "Unable to retrieve object."
-msgstr ""
-
-#: dashboards/project/containers/views.py:203
-msgid "Unable to list containers."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:7
-#: dashboards/project/containers/templates/containers/_copy.html:22
-#: dashboards/project/containers/templates/containers/copy.html:3
-#: dashboards/project/containers/templates/containers/copy.html:6
-msgid "Copy Object"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_copy.html:17
-msgid ""
-"Make a new copy of an existing object to store in this or another container."
-" You may also specify a path at which the new copy should live inside of the"
-" selected container."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_create.html:17
-msgid ""
-"A container is a storage compartment for your data and provides a way for "
-"you to organize your data. You can think of a container as a folder in "
-"Windows &reg; or a directory in UNIX &reg;. The primary difference between a"
-" container and these other file system concepts is that containers cannot be"
-" nested. You can, however, create an unlimited number of containers within "
-"your account. Data must be stored in a container so you must have at least "
-"one container defined in your account prior to uploading data."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:8
-msgid "Upload Object To Container"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:18
-msgid ""
-"An object is the basic storage entity that represents a file you store in "
-"the OpenStack Object Storage system. When you upload data to OpenStack "
-"Object Storage, the data is stored as-is (no compression or encryption) and "
-"consists of a location (container), the object's name, and any metadata "
-"consisting of key/value pairs."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid "Pseudo-folder"
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/_upload.html:19
-msgid ""
-"Within a container you can group your objects into pseudo-folders, which "
-"behave similarly to folders in your desktop operating system, with the "
-"exception that they are virtual collections defined by a common prefix on "
-"the object's name. A slash (/) character is used as the delimiter for "
-"pseudo-folders in the Object Store."
-msgstr ""
-
-#: dashboards/project/containers/templates/containers/upload.html:6
-msgid "Upload Objects"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/panel.py:26
-msgid "Images & Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:64
-msgid "Unable to retrieve images."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:75
-msgid "Unable to retrieve snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/views.py:84
-#: dashboards/project/volumes/forms.py:100
-msgid "Unable to retrieve volume snapshots."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:45
-msgid "Image Location"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:46
-msgid "An external (HTTP) URL to load the image from."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:49
-msgid "Image File"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:52
-#: dashboards/project/images_and_snapshots/images/forms.py:156
-#: dashboards/project/images_and_snapshots/images/tables.py:184
-msgid "Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:56
-msgid "AKI - Amazon Kernel Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:59
-msgid "AMI - Amazon Machine Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:62
-msgid "ARI - Amazon Ramdisk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:65
-msgid "ISO - Optical Disk Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:67
-msgid "QCOW2 - QEMU Emulator"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:74
-msgid "Minimum Disk (GB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:75
-#: dashboards/project/images_and_snapshots/images/forms.py:82
-msgid ""
-"The minimum disk size required to boot the image. If unspecified, this value"
-" defaults to 0 (no minimum)."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:81
-msgid "Minimum Ram (MB)"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:88
-#: dashboards/project/images_and_snapshots/images/forms.py:160
-#: dashboards/project/images_and_snapshots/images/tables.py:181
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:15
-msgid "Public"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:99
-msgid "A image or external image location must be specified."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:102
-msgid "Can not specify both image and external image location."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:132
-#, python-format
-msgid "Your image %s has been queued for creation."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:136
-msgid "Unable to create new image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:142
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:48
-msgid "Kernel ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:147
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:52
-msgid "Ramdisk ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:152
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:44
-msgid "Architecture"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:164
-#, python-format
-msgid "Unable to update image \"%s\"."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/forms.py:188
-msgid "Image was successfully updated."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:37
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:33
-#: dashboards/project/instances/workflows/create_instance.py:466
-msgid "Launch"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tables.py:49
-#: dashboards/project/images_and_snapshots/images/tables.py:131
-#: dashboards/project/instances/workflows/create_instance.py:171
-#: dashboards/project/instances/workflows/create_instance.py:176
-msgid "Image"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/tabs.py:38
-msgid "Unable to retrieve image details."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/images/views.py:61
-msgid "Unable to retrieve image."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:37
-msgid "Instance ID"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:40
-#: dashboards/project/volumes/forms.py:240
-msgid "Snapshot Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:50
-#, python-format
-msgid "Snapshot \"%(name)s\" created for instance \"%(inst)s\""
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/forms.py:56
-msgid "Unable to create snapshot."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:48
-#: dashboards/project/instances/workflows/create_instance.py:110
-#: dashboards/project/instances/workflows/create_instance.py:172
-msgid "Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:49
-msgid "Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/tables.py:55
-msgid "Instance Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/snapshots/views.py:53
-msgid "Unable to retrieve instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:3
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/index.html:6
-msgid "Images &amp; Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:3
-msgid "Image Overview"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:6
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:7
-#: dashboards/project/instances/templates/instances/_detail_overview.html:6
-#: dashboards/project/instances/workflows/update_instance.py:148
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:6
-msgid "Info"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:17
-msgid "Checksum"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:19
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:39
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:28
-msgid "Created"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:21
-msgid "Updated"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:27
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:34
-#: dashboards/project/instances/templates/instances/_detail_overview.html:19
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:23
-msgid "Specs"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:32
-msgid "Container Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:34
-msgid "Disk Format"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:40
-msgid "Custom Properties"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:56
-msgid "Euca2ools state"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/_detail_overview.html:64
-msgid "Image Type"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/images/detail.html:4
-msgid "Image Detail "
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:8
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:23
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:3
-#: dashboards/project/instances/tables.py:235
-#: dashboards/project/volumes/tables.py:78
-msgid "Create Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_create.html:18
-msgid "Snapshots preserve the disk state of a running instance."
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:20
-#: dashboards/project/instances/templates/instances/_detail_overview.html:97
-#: dashboards/project/instances/workflows/create_instance.py:78
-#: dashboards/project/instances/workflows/create_instance.py:113
-#: dashboards/project/volumes/tables.py:38
-#: dashboards/project/volumes/tables.py:193
-msgid "Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/_detail_overview.html:38
-#: dashboards/project/instances/templates/instances/_detail_overview.html:29
-#: dashboards/project/instances/templates/instances/_detail_overview.html:32
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:11
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:12
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:27
-msgid "GB"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/create.html:6
-msgid "Create a Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:3
-msgid "Volume Snapshot Details"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/templates/images_and_snapshots/snapshots/detail.html:6
-msgid "Volume Snapshot Detail"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:35
-#: dashboards/project/instances/workflows/create_instance.py:79
-msgid "Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:36
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:89
-msgid "Volume Snapshots"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:37
-#: dashboards/project/loadbalancers/tables.py:70
-#: dashboards/project/loadbalancers/tables.py:83
-#: dashboards/project/loadbalancers/tables.py:91
-#: dashboards/project/loadbalancers/tables.py:99
-#: dashboards/project/volumes/tables.py:40
-msgid "Scheduled deletion of"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:45
-#: dashboards/project/volumes/tables.py:61
-#: dashboards/project/volumes/templates/volumes/_create.html:8
-#: dashboards/project/volumes/templates/volumes/_create.html:55
-#: dashboards/project/volumes/templates/volumes/create.html:3
-msgid "Create Volume"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tables.py:84
-#: dashboards/project/volumes/forms.py:28
-msgid "Volume Name"
-msgstr ""
-
-#: dashboards/project/images_and_snapshots/volume_snapshots/tabs.py:41
-msgid "Unable to retrieve snapshot details."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:71
-msgid "Terminate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:72
-msgid "Scheduled termination of"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:86
-msgid "Hard Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:87
-msgid "Hard Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:103
-msgid "Soft Reboot"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:104
-msgid "Soft Rebooted"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-msgid "Pause"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:112
-#: dashboards/project/instances/tables.py:141
-msgid "Resume"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-msgid "Paused"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:113
-#: dashboards/project/instances/tables.py:142
-msgid "Resumed"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:141
-msgid "Suspend"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:142
-msgid "Suspended"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:170
-#: dashboards/project/instances/tables.py:191
-#: dashboards/project/instances/templates/instances/launch.html:3
-#: dashboards/project/instances/templates/instances/launch.html:6
-#: dashboards/project/instances/workflows/create_instance.py:465
-#: dashboards/project/network_topology/templates/network_topology/index.html:26
-msgid "Launch Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:189
-msgid "(Quota exceeded)"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:204
-#: dashboards/project/instances/templates/instances/update.html:3
-#: dashboards/project/instances/templates/instances/update.html:6
-#: dashboards/project/instances/workflows/update_instance.py:161
-msgid "Edit Instance"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:222
-msgid "Edit Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:245
-#: dashboards/project/instances/tabs.py:55
-msgid "Console"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:260
-msgid "View Log"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:275
-msgid "Confirm Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:287
-msgid "Revert Resize/Migrate"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:334
-#, python-format
-msgid "Successfully associated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:338
-msgid "Unable to associate floating IP."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:364
-#, python-format
-msgid "Successfully disassociated floating IP: %s"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:367
-msgid "No floating IPs to disassociate."
-msgstr ""
-
-#: dashboards/project/instances/tables.py:392
-#, python-format
-msgid "%(name)s | %(RAM)s RAM | %(VCPU)s VCPU | %(disk)s Disk"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:399
-#: dashboards/project/instances/tables.py:406
-msgid "Not available"
-msgstr ""
-
-#: dashboards/project/instances/tables.py:446
-#: dashboards/project/instances/workflows/create_instance.py:179
-#: usage/tables.py:57
-msgid "Instance Name"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:36
-msgid "Log"
-msgstr ""
-
-#: dashboards/project/instances/tabs.py:48
-#: dashboards/project/instances/views.py:105
-#, python-format
-msgid "Unable to get log for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:58
-msgid "Unable to retrieve instances."
-msgstr ""
-
-#: dashboards/project/instances/views.py:121
-#, python-format
-msgid "Unable to get VNC console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:133
-#, python-format
-msgid "Unable to get SPICE console for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/views.py:154
-msgid "Unable to retrieve instance details."
-msgstr ""
-
-#: dashboards/project/instances/views.py:190
-#, python-format
-msgid "Unable to retrieve details for instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:3
-msgid "Instance Console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid ""
-"If console is not responding to keyboard input: click the grey status bar "
-"below."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:5
-msgid "Click here to show only console"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:19
-msgid "console is currently unavailable. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_console.html:20
-msgid "Reload"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:4
-msgid "Instance Console Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:7
-msgid "Log Length"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:9
-msgid "Go"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_log.html:11
-msgid "View Full Log"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:3
-#: dashboards/project/overview/templates/overview/usage.html:3
-msgid "Instance Overview"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:27
-msgid "VCPU"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:28
-#: usage/tables.py:20
-msgid "Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:38
-msgid "IP Addresses"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:63
-msgid "No rules defined."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:72
-msgid "Meta"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:75
-msgid "Key Name"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:88
-msgid "Volumes Attached"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:92
-#: dashboards/project/volumes/tables.py:178
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:38
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:45
-msgid "Attached To"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:94
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:42
-msgid "on"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_detail_overview.html:98
-msgid "No volumes attached."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:2
-msgid ""
-"You can customize your instance after it's launched using the options "
-"available here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_customize_help.html:3
-msgid ""
-"The \"Customization Script\" field is analogous to \"User Data\" in other "
-"systems."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:3
-msgid "Specify the details for launching an instance."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:4
-msgid ""
-"The chart below shows the resources used by this project in relation to the "
-"project's quotas."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:6
-msgid "Flavor Details"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:13
-msgid "Total Disk"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:14
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "MB"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:21
-msgid "Number of Instances"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:29
-msgid "Number of VCPUs"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_details_help.html:37
-msgid "Total RAM"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_network_help.html:3
-msgid ""
-"Choose network from Available networks to Selected Networks by push button "
-"or drag and drop, you may change nic order by drag and drop as well. "
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_launch_volumes_help.html:3
-msgid ""
-"An instance can be launched with varying types of attached storage. You may "
-"select from those options here."
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:8
-msgid "Selected Networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/_update_networks.html:11
-msgid "Available networks"
-msgstr ""
-
-#: dashboards/project/instances/templates/instances/detail.html:3
-msgid "Instance Detail"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:56
-msgid "Project & User"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:69
-msgid "Don't boot from a volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:70
-msgid "Boot from volume."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:71
-msgid "Boot from volume snapshot (creates a new volume)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:75
-#: dashboards/project/instances/workflows/create_instance.py:93
-msgid "Volume Options"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:81
-#: dashboards/project/volumes/forms.py:170
-msgid "Device Name"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:84
-msgid "Volume mount point (e.g. 'vda' mounts at '/dev/vda')."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:86
-msgid "Delete on Terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:89
-msgid "Delete volume on instance terminate"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:103
-#, python-format
-msgid "Please choose a volume, or select %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:120
-msgid "Select Volume"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:128
-msgid "Unable to retrieve list of volumes."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:132
-msgid "Select Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:141
-msgid "Unable to retrieve list of volume snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:174
-msgid "Instance Source"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:177
-msgid "Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:181
-msgid "Size of image to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:182
-msgid "Instance Count"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:185
-msgid "Number of instances to launch."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:188
-msgid "Details"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:201
-msgid ""
-"There are no image sources available; you must first create an image before "
-"attempting to launch an instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:206
-msgid "Please select an option for the instance source."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:215
-msgid ""
-"Launching multiple instances is only supported for images and instance "
-"snapshots."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:232
-msgid "Unable to retrieve public images."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:248
-msgid "Unable to retrieve images for the current project."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:271
-msgid "Select Image"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:273
-msgid "No images available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:282
-msgid "Select Instance Snapshot"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:284
-msgid "No snapshots available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:295
-msgid "Unable to retrieve instance flavors."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:308
-#: usage/base.py:115
-msgid "Unable to retrieve quota information."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:341
-msgid "Which keypair to use for authentication."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:348
-msgid "Launch instance in these security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:353
-msgid ""
-"Control access to your instance via keypairs, security groups, and other "
-"mechanisms."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:363
-msgid "Unable to retrieve keypairs."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:367
-msgid "Select a keypair"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:369
-msgid "No keypairs available."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:378
-msgid "Unable to retrieve list of security groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:398
-msgid "Customization Script"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:400
-msgid ""
-"A script or set of commands to be executed after the instance has been built"
-" (max 16kb)."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:407
-msgid "Post-Creation"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:423
-msgid "At least one network must be specified."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:425
-msgid "Launch instance withthese networks"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:429
-msgid "Networking"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:431
-msgid "Select networks for your instance."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:443
-msgid "Unable to retrieve networks."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:467
-#, python-format
-msgid "Launched %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:468
-#, python-format
-msgid "Unable to launch %(count)s named \"%(name)s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:481
-#, python-format
-msgid "%s instances"
-msgstr ""
-
-#: dashboards/project/instances/workflows/create_instance.py:484
-msgid "instance"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:47
-msgid "Unable to retrieve security group list. Please try again later."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:81
-#, python-format
-msgid "Couldn't get current security group list for instance %s."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:103
-#, python-format
-msgid "Failed to modify %d instance security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:117
-msgid ""
-"From here you can add and remove security groups to this project from the "
-"list of available security groups."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:119
-msgid "All Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:120
-msgid "Instance Security Groups"
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:121
-msgid "No security groups found."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:122
-msgid "No security groups enabled."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:150
-msgid "From here you can edit the instance details."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:163
-#, python-format
-msgid "Modified instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/instances/workflows/update_instance.py:164
-#, python-format
-msgid "Unable to modify instance \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/panel.py:10
-msgid "Load Balancers"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:32
-#: dashboards/project/loadbalancers/workflows.py:96
-msgid "Add Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:39
-#: dashboards/project/loadbalancers/workflows.py:193
-msgid "Add Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:55
-#: dashboards/project/loadbalancers/workflows.py:325
-msgid "Add Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:62
-#: dashboards/project/loadbalancers/workflows.py:429
-msgid "Add Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:69
-#: dashboards/project/loadbalancers/tables.py:82
-#: dashboards/project/loadbalancers/tables.py:90
-#: dashboards/project/loadbalancers/tables.py:98
-msgid "Delete"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:71
-msgid "Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:72
-msgid "Vips"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:85
-#: dashboards/project/loadbalancers/tables.py:121
-#: dashboards/project/loadbalancers/tabs.py:32
-msgid "Pools"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:92
-msgid "Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:93
-#: dashboards/project/loadbalancers/tables.py:160
-#: dashboards/project/loadbalancers/tabs.py:68
-msgid "Monitors"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:100
-msgid "Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:101
-#: dashboards/project/loadbalancers/tables.py:147
-#: dashboards/project/loadbalancers/tabs.py:50
-msgid "Members"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:116
-msgid "VIP"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:141
-#: dashboards/project/loadbalancers/workflows.py:131
-#: dashboards/project/loadbalancers/workflows.py:257
-msgid "Protocol Port"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tables.py:156
-msgid "Monitor Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:44
-#: dashboards/project/loadbalancers/workflows.py:270
-#: dashboards/project/loadbalancers/workflows.py:388
-msgid "Unable to retrieve pools list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:62
-msgid "Unable to retrieve member list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:79
-msgid "Unable to retrieve monitor list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:90
-msgid "Pool Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:101
-msgid "Unable to retrieve pool details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:106
-msgid "Vip Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:117
-msgid "Unable to retrieve vip details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:122
-msgid "Member Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:133
-msgid "Unable to retrieve member details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:138
-msgid "Monitor Details"
-msgstr ""
-
-#: dashboards/project/loadbalancers/tabs.py:149
-msgid "Unable to retrieve monitor details."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:55
-msgid "Unable to delete monitor."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:62
-msgid "Must delete Vip first."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:69
-msgid "Unable to delete member."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:76
-msgid "Unable to locate vip to delete."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:82
-msgid "Unable to delete vip."
-msgstr ""
-
-#: dashboards/project/loadbalancers/views.py:112
-msgid "Unable to retrieve pool subnet."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:40
-msgid "Load Balancing Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:49
-msgid "Select a Subnet"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:54
-msgid "Unable to retrieve networks list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:60
-#: dashboards/project/loadbalancers/workflows.py:65
-#: dashboards/project/loadbalancers/workflows.py:152
-msgid "Select a Protocol"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:72
-msgid "PoolDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:74
-msgid ""
-"Create Pool for current tenant.\n"
-"\n"
-"Assign a name and description for the pool. Choose one subnet where all members of this pool must be on. Select the protocol and load balancing method for this pool. Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:98
-#, python-format
-msgid "Added Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:99
-#, python-format
-msgid "Unable to add Pool \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:124
-msgid "Vip Address from Floating IPs"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:134
-msgid "Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:137
-msgid "Cookie Name"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:138
-msgid "Required for APP_COOKIE persistence; Ignored otherwise."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:141
-msgid "Connection Limit"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:148
-#, python-format
-msgid "Specify a free IP address from %s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:157
-msgid "Set Session Persistence"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:163
-msgid "Currently Not Supported"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:167
-msgid "AddVip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:169
-msgid ""
-"Create a vip (virtual IP) for this pool. Assign a name and description for "
-"the vip. Specify an IP address and port for the vip. Choose the protocol and"
-" session persistence method for the vip.Specify the max connections allowed."
-" Admin State is UP (checked) by default."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:195
-#, python-format
-msgid "Added Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:196
-#, python-format
-msgid "Unable to add Vip \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:209
-#, python-format
-msgid "Only one address can be specified.Unable to add Vip %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:220
-msgid "Unable to retrieve pool."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:227
-msgid "Cookie name must be specified with APP_COOKIE persistence."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:251
-msgid "Member(s)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:255
-#: dashboards/project/loadbalancers/workflows.py:289
-msgid "Select members for this pool "
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:256
-msgid "Weight"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:264
-#: dashboards/project/loadbalancers/workflows.py:383
-msgid "Select a Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:283
-msgid "Unable to retrieve instances list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:286
-msgid "No servers available. Click Add to cancel."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:303
-msgid "MemberDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:305
-msgid ""
-"Add member to selected pool.\n"
-"\n"
-"Choose one or more listed instances to be added to the pool as member(s). Assign a numeric weight for this member Specify the port number the member(s) operate on; e.g., 80."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:327
-#, python-format
-msgid "Added Member \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:328
-#, python-format
-msgid "Unable to add Member %s."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:338
-#, python-format
-msgid "No instances available.%s"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:349
-msgid "Unable to retrieve ports list."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:366
-msgid "Delay"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:367
-msgid "Timeout"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:369
-msgid "Max Retries (1~10)"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:371
-msgid "HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:373
-msgid "URL"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:376
-msgid "Expected HTTP Status Codes"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:393
-msgid "Select Type"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:400
-msgid "Select HTTP Method"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:405
-msgid "MonitorDetails"
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:407
-msgid ""
-"Create a monitor for a pool.\n"
-"\n"
-"Select target pool and type of monitoring. Specify delay, timeout, and retry limits required by the monitor. Specify method, URL path, and expected HTTP codes upon success."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:431
-#, python-format
-msgid "Added Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/workflows.py:432
-#, python-format
-msgid "Unable to add Monitor \"%s\"."
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:6
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:6
-msgid "ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:9
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:9
-msgid "Tenant ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:30
-msgid "Pool ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:21
-msgid "Address: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:24
-msgid "Protocol Port: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:21
-msgid "Weight: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:33
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:42
-msgid "Admin State Up: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_member_details.html:27
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:36
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:39
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:45
-msgid "Status: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:12
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:34
-msgid "Type: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:15
-msgid "Delay: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:18
-msgid "Timeout: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:21
-msgid "Max Retries: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:24
-msgid "HTTP Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:27
-msgid "URL Path: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_monitor_details.html:30
-msgid "Expected Codes: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:12
-msgid "VIP ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:15
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:12
-msgid "Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:18
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:15
-msgid "Description: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:21
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:18
-msgid "Subnet ID: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:24
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:27
-msgid "Protocol: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:27
-msgid "Load Balancing Method: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:30
-msgid "Members: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_pool_details.html:33
-msgid "Health Monitors: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:33
-msgid "Session Persistence: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:36
-msgid "Cookie Name: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/_vip_details.html:39
-msgid "Connection Limit: "
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmember.html:6
-msgid "Add New Member"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addmonitor.html:6
-msgid "Add New Monitor"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addpool.html:6
-msgid "Add New Pool"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/addvip.html:6
-msgid "Specify Vip"
-msgstr ""
-
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:3
-#: dashboards/project/loadbalancers/templates/loadbalancers/details_tabs.html:6
-msgid "Load Balancer"
-msgstr ""
-
-#: dashboards/project/network_topology/panel.py:29
-#: dashboards/project/network_topology/templates/network_topology/index.html:3
-#: dashboards/project/network_topology/templates/network_topology/index.html:6
-msgid "Network Topology"
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:23
-msgid "This pane needs javascript support."
-msgstr ""
-
-#: dashboards/project/network_topology/templates/network_topology/index.html:33
-msgid "There are no networks, routers, or connected instances to display. "
-msgstr ""
-
-#: dashboards/project/networks/tables.py:81
-msgid "Add Subnet"
-msgstr ""
-
-#: dashboards/project/networks/views.py:86
-msgid "Unable to retrieve network details."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:39
-msgid "Network Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:47
-msgid ""
-"From here you can create a new network.\n"
-"In addition a subnet associated with the network can be created in the next panel."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:61
-msgid "Subnet Name"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:62
-msgid "Subnet Name. This field is optional."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:65
-#: dashboards/project/networks/subnets/tables.py:84
-#: dashboards/project/networks/subnets/workflows.py:85
-msgid "Network Address"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:68
-#: dashboards/project/networks/subnets/workflows.py:90
-msgid "Network address in CIDR format (e.g. 192.168.0.0/24)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:75
-#: dashboards/project/networks/subnets/workflows.py:109
-msgid "Gateway IP (optional)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:78
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254) The default value is the first IP"
-" of the network address (e.g. 192.168.0.1 for 192.168.0.0/24). If you use "
-"the default, leave blank. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:87
-#: dashboards/project/networks/subnets/workflows.py:119
-msgid "Disable Gateway"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:92
-msgid ""
-"You can create a subnet associated with the new network, in which case "
-"\"Network Address\" must be specified. If you wish to create a network "
-"WITHOUT a subnet, uncheck the \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:103
-msgid "Specify \"Network Address\" or clear \"Create Subnet\" checkbox."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:109
-msgid "Network Address and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:113
-#, python-format
-msgid "The subnet in the Network Address is too small (/%s)."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:118
-msgid "Gateway IP and IP version are inconsistent."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:121
-msgid "Specify IP address of gateway or check \"Disable Gateway\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:141
-msgid "Enable DHCP"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:145
-msgid "Allocation Pools"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:146
-msgid ""
-"IP address allocation pools. Each entry is "
-"&lt;start_ip_address&gt;,&lt;end_ip_address&gt; (e.g., "
-"192.168.1.100,192.168.1.120) and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:153
-msgid "DNS Name Servers"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:154
-msgid ""
-"IP address list of DNS name servers for this subnet. One entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:159
-msgid "Host Routes"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:160
-msgid ""
-"Additional routes announced to the hosts. Each entry is "
-"&lt;destination_cidr&gt;,&lt;nexthop&gt; (e.g., "
-"192.168.200.0/24,10.56.1.254)and one entry per line."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:168
-#: dashboards/project/networks/subnets/workflows.py:145
-msgid "You can specify additional attributes for the subnet."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:174
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(ip)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:182
-#, python-format
-msgid "%(field_name)s: Invalid IP address (value=%(network)s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:193
-#, python-format
-msgid "Start and end addresses must be specified (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:199
-#, python-format
-msgid "Start address is larger than end address (value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:217
-#, python-format
-msgid ""
-"Host Routes format error: Destination CIDR and nexthop must be specified "
-"(value=%s)"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:242
-#, python-format
-msgid "Created network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:243
-#, python-format
-msgid "Unable to create network \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:265
-#, python-format
-msgid "Network \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:269
-#, python-format
-msgid "Failed to create network \"%(network)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:325
-#, python-format
-msgid "Subnet \"%s\" was successfully created."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:329
-#, python-format
-msgid "Failed to create subnet \"%(sub)s\" for network \"%(net)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:345
-#, python-format
-msgid "Delete the created network \"%s\" due to subnet creation failure."
-msgstr ""
-
-#: dashboards/project/networks/workflows.py:353
-#, python-format
-msgid "Failed to delete network \"%s\""
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:39
-msgid "Attached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:41
-msgid "Detached"
-msgstr ""
-
-#: dashboards/project/networks/ports/tables.py:60
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:35
-msgid "Attached Device"
-msgstr ""
-
-#: dashboards/project/networks/ports/views.py:53
-msgid "Unable to retrieve port details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/tabs.py:42
-msgid "Unable to retrieve subnet details."
-msgstr ""
-
-#: dashboards/project/networks/subnets/views.py:71
-msgid "Unable to retrieve subnet details"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:43
-msgid ""
-"You can create a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:62
-#, python-format
-msgid "Created subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:63
-#, python-format
-msgid "Unable to create subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:112
-msgid ""
-"IP address of Gateway (e.g. 192.168.0.254). You need to specify an explicit "
-"address to set the gateway. If you want to use no gateway, check 'Disable "
-"Gateway' below."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:124
-msgid ""
-"You can update a subnet associated with the network. Advanced configuration "
-"are available at \"Subnet Detail\" tab."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:155
-msgid "Update"
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:156
-#, python-format
-msgid "Updated subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:157
-#, python-format
-msgid "Unable to update subnet \"%s\"."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:185
-#, python-format
-msgid "Subnet \"%s\" was successfully updated."
-msgstr ""
-
-#: dashboards/project/networks/subnets/workflows.py:189
-#, python-format
-msgid "Failed to update subnet \"%(sub)s\": %(reason)s"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:3
-msgid "Network Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:22
-msgid "Provider Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:23
-msgid "Network Type"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:24
-msgid "Physical Network"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/_detail_overview.html:25
-msgid "Segmentation ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/detail.html:6
-msgid "Network Detail: "
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:3
-msgid "Port Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:18
-msgid "Fixed IP"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:22
-msgid "IP address:"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:23
-msgid "Subnet ID"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/_detail_overview.html:29
-msgid "Mac Address"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/ports/detail.html:3
-#: dashboards/project/networks/templates/networks/ports/detail.html:6
-msgid "Port Detail"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:3
-msgid "Subnet Overview"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:16
-msgid "IP version"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:20
-msgid "IP allocation pool"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:23
-msgid "Start"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:24
-msgid " - End"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:27
-msgid "DHCP Enable"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:31
-msgid "Additional routes"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:34
-msgid "Destination"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:35
-msgid " : Next hop"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:37
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:45
-msgid "None"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/_detail_overview.html:40
-msgid "DNS name server"
-msgstr ""
-
-#: dashboards/project/networks/templates/networks/subnets/detail.html:3
-#: dashboards/project/networks/templates/networks/subnets/detail.html:6
-msgid "Subnet Detail"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:33
-msgid "Router"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:43
-#: dashboards/project/routers/tables.py:49
-#, python-format
-msgid "Unable to delete router \"%s\""
-msgstr ""
-
-#: dashboards/project/routers/tables.py:78
-msgid "Clear"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:79
-msgid "Cleared"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:80
-#: dashboards/project/routers/ports/tables.py:33
-msgid "Gateway"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:81
-msgid "Gateways"
-msgstr ""
-
-#: dashboards/project/routers/tables.py:91
-#, python-format
-msgid "Unable to clear gateway for router \"%(name)s\": \"%(msg)s\""
-msgstr ""
-
-#: dashboards/project/routers/tabs.py:37
-msgid "Unable to retrieve router details."
-msgstr ""
-
-#: dashboards/project/routers/views.py:77
-#, python-format
-msgid "Unable to retrieve a list of external networks \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:89
-#, python-format
-msgid "External network \"%s\" not found."
-msgstr ""
-
-#: dashboards/project/routers/views.py:105
-#, python-format
-msgid "Unable to retrieve details for router \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/views.py:117
-#, python-format
-msgid "Unable to retrieve an external network \"%s\"."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:35
-#: dashboards/project/routers/ports/forms.py:94
-msgid "Router ID"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:51
-#: dashboards/project/routers/ports/forms.py:109
-#, python-format
-msgid "Failed to get network list %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:67
-msgid "Select Subnet"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:69
-msgid "No subnets available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:77
-msgid "Interface added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:82
-#, python-format
-msgid "Failed to add_interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:118
-msgid "Select network"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:120
-msgid "No networks available."
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:128
-msgid "Gateway interface is added"
-msgstr ""
-
-#: dashboards/project/routers/ports/forms.py:133
-#, python-format
-msgid "Failed to set gateway %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:50
-msgid "Interface"
-msgstr ""
-
-#: dashboards/project/routers/ports/tables.py:65
-#, python-format
-msgid "Failed to delete interface %s"
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:50
-msgid "Unable to retrieve router."
-msgstr ""
-
-#: dashboards/project/routers/ports/views.py:82
-msgid "Unable to set gateway."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:33
-msgid "Size (GB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:34
-msgid "Encryption"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:35
-msgid "Use snapshot as a source"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:84
-#, python-format
-msgid "Volume size must be equal to or greater than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:89
-msgid "Unable to load the specified snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:94
-msgid "Choose a snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:118
-#, python-format
-msgid "The volume size cannot be less than the snapshot size (%sGB)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:127
-#, python-format
-msgid ""
-"A volume of %(req)iGB cannot be created as you only have %(avail)iGB of your"
-" quota available."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:134
-msgid "You are already using all of your available volumes."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:158
-msgid "Unable to create volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:167
-msgid "Attach to Instance"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:168
-msgid "Select an instance to attach to."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:212
-msgid "Unknown instance (None)"
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:226
-#, python-format
-msgid "Attaching volume %(vol)s to instance %(inst)s on %(dev)s."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:235
-msgid "Unable to attach volume."
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:259
-#, python-format
-msgid "Creating volume snapshot \"%s\""
-msgstr ""
-
-#: dashboards/project/volumes/forms.py:265
-msgid "Unable to create volume snapshot."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:48
-#, python-format
-msgid "Unable to delete volume \"%s\". One or more snapshots depend on it."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:68
-msgid "Edit Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:97
-#, python-format
-msgid "%sGB"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:110
-#: dashboards/project/volumes/views.py:152
-msgid "Unable to retrieve attachment information."
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:127
-#, python-format
-msgid "Attached to %(instance)s on %(dev)s"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:191
-msgid "Detach"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:192
-msgid "Detaching"
-msgstr ""
-
-#: dashboards/project/volumes/tables.py:229
-#, python-format
-msgid "%(dev)s on instance %(instance_name)s"
-msgstr ""
-
-#: dashboards/project/volumes/tabs.py:41
-msgid "Unable to retrieve volume details."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:49
-msgid "Unable to retrieve volume list."
-msgstr ""
-
-#: dashboards/project/volumes/views.py:56
-msgid "Unable to retrieve volume/instance attachment information"
-msgstr ""
-
-#: dashboards/project/volumes/views.py:133
-#: dashboards/project/volumes/views.py:143
-msgid "Unable to retrieve volume information."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:9
-#: dashboards/project/volumes/templates/volumes/attach.html:3
-#: dashboards/project/volumes/templates/volumes/attach.html:6
-msgid "Manage Volume Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:13
-msgid "Attach To Instance"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_attach.html:22
-msgid "Attach Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:20
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:18
-msgid "Volumes are block devices that can be attached to instances."
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:22
-msgid "Volume Quotas"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:25
-msgid "Total Gigabytes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create.html:34
-msgid "Number of Volumes"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:8
-#: dashboards/project/volumes/templates/volumes/_create_snapshot.html:23
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:3
-msgid "Create Volume Snapshot"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:3
-msgid "Volume Overview"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:34
-msgid "Attachments"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:46
-msgid "Not attached"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/_detail_overview.html:52
-msgid "Metadata"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create.html:6
-msgid "Create a Volume"
-msgstr ""
-
-#: dashboards/project/volumes/templates/volumes/create_snapshot.html:6
-msgid "Create a Volume Snapshot"
-msgstr ""
-
-#: dashboards/settings/dashboard.py:24 templates/_header.html:4
-msgid "Settings"
-msgstr ""
-
-#: dashboards/settings/user/forms.py:73
-msgid "Settings saved."
-msgstr ""
-
-#: dashboards/settings/user/panel.py:25
-#: dashboards/settings/user/templates/user/_settings.html:8
-#: dashboards/settings/user/templates/user/settings.html:3
-#: dashboards/settings/user/templates/user/settings.html:6
-msgid "User Settings"
-msgstr ""
-
-#: dashboards/settings/user/templates/user/_settings.html:18
-msgid "From here you can modify dashboard settings for your user."
-msgstr ""
-
-#: templates/403.html:4 templates/403.html.py:9
-msgid "Forbidden"
-msgstr "禁止"
-
-#: templates/403.html:20 templates/404.html:19 templates/500.html:73
-msgid "Home"
-msgstr "主頁"
-
-#: templates/404.html:4
-msgid "Page Not Found"
-msgstr "頁面不存在"
-
-#: templates/404.html:9
-msgid "The page you were looking for doesn't exist"
-msgstr "您所查看的頁面並不存在"
-
-#: templates/404.html:10
-msgid "You may have mistyped the address or the page may have moved."
-msgstr "您可能輸入錯的位址或此頁面已被移除"
-
-#: templates/500.html:20
-msgid "Server error"
-msgstr ""
-
-#: templates/500.html:67
-msgid "Something went wrong!"
-msgstr ""
-
-#: templates/500.html:68
-msgid ""
-"An unexpected error has occurred. Try refreshing the page. If that doesn't "
-"help, contact your local administrator."
-msgstr ""
-
-#: templates/500.html:74 templates/_header.html:6
-msgid "Help"
-msgstr ""
-
-#: templates/_header.html:3
-msgid "Logged in as"
-msgstr ""
-
-#: templates/_header.html:8
-msgid "Sign Out"
-msgstr ""
-
-#: test/settings.py:49
-msgid "Password must be between 8 and 18 characters."
-msgstr ""
-
-#: usage/base.py:98
-msgid "Unable to retrieve usage information."
-msgstr ""
-
-#: usage/base.py:101
-msgid "You are viewing data for the future, which may or may not exist."
-msgstr ""
-
-#: usage/tables.py:11
-msgid "Download CSV Summary"
-msgstr ""
-
-#: usage/tables.py:25
-msgid "VCPU Hours"
-msgstr ""
-
-#: usage/tables.py:30
-msgid "Project Name"
-msgstr ""
-
-#: usage/tables.py:32
-msgid "Disk GB Hours"
-msgstr ""
-
-#: usage/tables.py:40 usage/tables.py:68
-msgid "Usage Summary"
-msgstr ""
-
-#: usage/tables.py:60
-msgid "Uptime"
-msgstr ""
diff --git a/openstack_dashboard/openstack/__init__.py b/openstack_dashboard/openstack/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/openstack/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/openstack/common/__init__.py b/openstack_dashboard/openstack/common/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/openstack/common/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/openstack/common/config/__init__.py b/openstack_dashboard/openstack/common/config/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/openstack/common/config/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/openstack/common/config/generator.py b/openstack_dashboard/openstack/common/config/generator.py
deleted file mode 100755
index 5eb2c2c9..00000000
--- a/openstack_dashboard/openstack/common/config/generator.py
+++ /dev/null
@@ -1,253 +0,0 @@
-#!/usr/bin/env python
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 SINA Corporation
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-#
-# @author: Zhongyue Luo, SINA Corporation.
-#
-"""Extracts OpenStack config option info from module(s)."""
-
-import imp
-import os
-import re
-import socket
-import sys
-import textwrap
-
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common import gettextutils
-from openstack_dashboard.openstack.common import importutils
-
-gettextutils.install('openstack_dashboard')
-
-STROPT = "StrOpt"
-BOOLOPT = "BoolOpt"
-INTOPT = "IntOpt"
-FLOATOPT = "FloatOpt"
-LISTOPT = "ListOpt"
-MULTISTROPT = "MultiStrOpt"
-
-OPT_TYPES = {
- STROPT: 'string value',
- BOOLOPT: 'boolean value',
- INTOPT: 'integer value',
- FLOATOPT: 'floating point value',
- LISTOPT: 'list value',
- MULTISTROPT: 'multi valued',
-}
-
-OPTION_COUNT = 0
-OPTION_REGEX = re.compile(r"(%s)" % "|".join([STROPT, BOOLOPT, INTOPT,
- FLOATOPT, LISTOPT,
- MULTISTROPT]))
-
-PY_EXT = ".py"
-BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../"))
-WORDWRAP_WIDTH = 60
-
-
-def generate(srcfiles):
- mods_by_pkg = dict()
- for filepath in srcfiles:
- pkg_name = filepath.split(os.sep)[1]
- mod_str = '.'.join(['.'.join(filepath.split(os.sep)[:-1]),
- os.path.basename(filepath).split('.')[0]])
- mods_by_pkg.setdefault(pkg_name, list()).append(mod_str)
- # NOTE(lzyeval): place top level modules before packages
- pkg_names = filter(lambda x: x.endswith(PY_EXT), mods_by_pkg.keys())
- pkg_names.sort()
- ext_names = filter(lambda x: x not in pkg_names, mods_by_pkg.keys())
- ext_names.sort()
- pkg_names.extend(ext_names)
-
- # opts_by_group is a mapping of group name to an options list
- # The options list is a list of (module, options) tuples
- opts_by_group = {'DEFAULT': []}
-
- for pkg_name in pkg_names:
- mods = mods_by_pkg.get(pkg_name)
- mods.sort()
- for mod_str in mods:
- if mod_str.endswith('.__init__'):
- mod_str = mod_str[:mod_str.rfind(".")]
-
- mod_obj = _import_module(mod_str)
- if not mod_obj:
- continue
-
- for group, opts in _list_opts(mod_obj):
- opts_by_group.setdefault(group, []).append((mod_str, opts))
-
- print_group_opts('DEFAULT', opts_by_group.pop('DEFAULT', []))
- for group, opts in opts_by_group.items():
- print_group_opts(group, opts)
-
- print "# Total option count: %d" % OPTION_COUNT
-
-
-def _import_module(mod_str):
- try:
- if mod_str.startswith('bin.'):
- imp.load_source(mod_str[4:], os.path.join('bin', mod_str[4:]))
- return sys.modules[mod_str[4:]]
- else:
- return importutils.import_module(mod_str)
- except ImportError as ie:
- sys.stderr.write("%s\n" % str(ie))
- return None
- except Exception:
- return None
-
-
-def _is_in_group(opt, group):
- "Check if opt is in group."
- for key, value in group._opts.items():
- if value['opt'] == opt:
- return True
- return False
-
-
-def _guess_groups(opt, mod_obj):
- # is it in the DEFAULT group?
- if _is_in_group(opt, cfg.CONF):
- return 'DEFAULT'
-
- # what other groups is it in?
- for key, value in cfg.CONF.items():
- if isinstance(value, cfg.CONF.GroupAttr):
- if _is_in_group(opt, value._group):
- return value._group.name
-
- raise RuntimeError(
- "Unable to find group for option %s, "
- "maybe it's defined twice in the same group?"
- % opt.name
- )
-
-
-def _list_opts(obj):
- def is_opt(o):
- return (isinstance(o, cfg.Opt) and
- not isinstance(o, cfg.SubCommandOpt))
-
- opts = list()
- for attr_str in dir(obj):
- attr_obj = getattr(obj, attr_str)
- if is_opt(attr_obj):
- opts.append(attr_obj)
- elif (isinstance(attr_obj, list) and
- all(map(lambda x: is_opt(x), attr_obj))):
- opts.extend(attr_obj)
-
- ret = {}
- for opt in opts:
- ret.setdefault(_guess_groups(opt, obj), []).append(opt)
- return ret.items()
-
-
-def print_group_opts(group, opts_by_module):
- print "[%s]" % group
- print
- global OPTION_COUNT
- for mod, opts in opts_by_module:
- OPTION_COUNT += len(opts)
- print '#'
- print '# Options defined in %s' % mod
- print '#'
- print
- for opt in opts:
- _print_opt(opt)
- print
-
-
-def _get_my_ip():
- try:
- csock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- csock.connect(('8.8.8.8', 80))
- (addr, port) = csock.getsockname()
- csock.close()
- return addr
- except socket.error:
- return None
-
-
-def _sanitize_default(s):
- """Set up a reasonably sensible default for pybasedir, my_ip and host."""
- if s.startswith(BASEDIR):
- return s.replace(BASEDIR, '/usr/lib/python/site-packages')
- elif BASEDIR in s:
- return s.replace(BASEDIR, '')
- elif s == _get_my_ip():
- return '10.0.0.1'
- elif s == socket.getfqdn():
- return 'openstack_dashboard'
- elif s.strip() != s:
- return '"%s"' % s
- return s
-
-
-def _print_opt(opt):
- opt_name, opt_default, opt_help = opt.dest, opt.default, opt.help
- if not opt_help:
- sys.stderr.write('WARNING: "%s" is missing help string.\n' % opt_name)
- opt_type = None
- try:
- opt_type = OPTION_REGEX.search(str(type(opt))).group(0)
- except (ValueError, AttributeError) as err:
- sys.stderr.write("%s\n" % str(err))
- sys.exit(1)
- opt_help += ' (' + OPT_TYPES[opt_type] + ')'
- print '#', "\n# ".join(textwrap.wrap(opt_help, WORDWRAP_WIDTH))
- try:
- if opt_default is None:
- print '#%s=<None>' % opt_name
- elif opt_type == STROPT:
- assert(isinstance(opt_default, basestring))
- print '#%s=%s' % (opt_name, _sanitize_default(opt_default))
- elif opt_type == BOOLOPT:
- assert(isinstance(opt_default, bool))
- print '#%s=%s' % (opt_name, str(opt_default).lower())
- elif opt_type == INTOPT:
- assert(isinstance(opt_default, int) and
- not isinstance(opt_default, bool))
- print '#%s=%s' % (opt_name, opt_default)
- elif opt_type == FLOATOPT:
- assert(isinstance(opt_default, float))
- print '#%s=%s' % (opt_name, opt_default)
- elif opt_type == LISTOPT:
- assert(isinstance(opt_default, list))
- print '#%s=%s' % (opt_name, ','.join(opt_default))
- elif opt_type == MULTISTROPT:
- assert(isinstance(opt_default, list))
- if not opt_default:
- opt_default = ['']
- for default in opt_default:
- print '#%s=%s' % (opt_name, default)
- print
- except Exception:
- sys.stderr.write('Error in option "%s"\n' % opt_name)
- sys.exit(1)
-
-
-def main():
- if len(sys.argv) < 2:
- print "usage: %s [srcfile]...\n" % sys.argv[0]
- sys.exit(0)
- generate(sys.argv[1:])
-
-if __name__ == '__main__':
- main()
diff --git a/openstack_dashboard/openstack/common/context.py b/openstack_dashboard/openstack/common/context.py
deleted file mode 100644
index be8ba8b0..00000000
--- a/openstack_dashboard/openstack/common/context.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Simple class that stores security context information in the web request.
-
-Projects should subclass this class if they wish to enhance the request
-context or provide additional information in their specific WSGI pipeline.
-"""
-
-import itertools
-
-from openstack_dashboard.openstack.common import uuidutils
-
-
-def generate_request_id():
- return 'req-%s' % uuidutils.generate_uuid()
-
-
-class RequestContext(object):
-
- """
- Stores information about the security context under which the user
- accesses the system, as well as additional request information.
- """
-
- def __init__(self, auth_token=None, user=None, tenant=None, is_admin=False,
- read_only=False, show_deleted=False, request_id=None):
- self.auth_token = auth_token
- self.user = user
- self.tenant = tenant
- self.is_admin = is_admin
- self.read_only = read_only
- self.show_deleted = show_deleted
- if not request_id:
- request_id = generate_request_id()
- self.request_id = request_id
-
- def to_dict(self):
- return {'user': self.user,
- 'tenant': self.tenant,
- 'is_admin': self.is_admin,
- 'read_only': self.read_only,
- 'show_deleted': self.show_deleted,
- 'auth_token': self.auth_token,
- 'request_id': self.request_id}
-
-
-def get_admin_context(show_deleted="no"):
- context = RequestContext(None,
- tenant=None,
- is_admin=True,
- show_deleted=show_deleted)
- return context
-
-
-def get_context_from_function_and_args(function, args, kwargs):
- """Find an arg of type RequestContext and return it.
-
- This is useful in a couple of decorators where we don't
- know much about the function we're wrapping.
- """
-
- for arg in itertools.chain(kwargs.values(), args):
- if isinstance(arg, RequestContext):
- return arg
-
- return None
diff --git a/openstack_dashboard/openstack/common/eventlet_backdoor.py b/openstack_dashboard/openstack/common/eventlet_backdoor.py
deleted file mode 100644
index 57b89ae9..00000000
--- a/openstack_dashboard/openstack/common/eventlet_backdoor.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 OpenStack Foundation.
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from __future__ import print_function
-
-import gc
-import pprint
-import sys
-import traceback
-
-import eventlet
-import eventlet.backdoor
-import greenlet
-from oslo.config import cfg
-
-eventlet_backdoor_opts = [
- cfg.IntOpt('backdoor_port',
- default=None,
- help='port for eventlet backdoor to listen')
-]
-
-CONF = cfg.CONF
-CONF.register_opts(eventlet_backdoor_opts)
-
-
-def _dont_use_this():
- print("Don't use this, just disconnect instead")
-
-
-def _find_objects(t):
- return filter(lambda o: isinstance(o, t), gc.get_objects())
-
-
-def _print_greenthreads():
- for i, gt in enumerate(_find_objects(greenlet.greenlet)):
- print(i, gt)
- traceback.print_stack(gt.gr_frame)
- print()
-
-
-def _print_nativethreads():
- for threadId, stack in sys._current_frames().items():
- print(threadId)
- traceback.print_stack(stack)
- print()
-
-
-def initialize_if_enabled():
- backdoor_locals = {
- 'exit': _dont_use_this, # So we don't exit the entire process
- 'quit': _dont_use_this, # So we don't exit the entire process
- 'fo': _find_objects,
- 'pgt': _print_greenthreads,
- 'pnt': _print_nativethreads,
- }
-
- if CONF.backdoor_port is None:
- return None
-
- # NOTE(johannes): The standard sys.displayhook will print the value of
- # the last expression and set it to __builtin__._, which overwrites
- # the __builtin__._ that gettext sets. Let's switch to using pprint
- # since it won't interact poorly with gettext, and it's easier to
- # read the output too.
- def displayhook(val):
- if val is not None:
- pprint.pprint(val)
- sys.displayhook = displayhook
-
- sock = eventlet.listen(('localhost', CONF.backdoor_port))
- port = sock.getsockname()[1]
- eventlet.spawn_n(eventlet.backdoor.backdoor_server, sock,
- locals=backdoor_locals)
- return port
diff --git a/openstack_dashboard/openstack/common/excutils.py b/openstack_dashboard/openstack/common/excutils.py
deleted file mode 100644
index a5144815..00000000
--- a/openstack_dashboard/openstack/common/excutils.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 OpenStack Foundation.
-# Copyright 2012, Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Exception related utilities.
-"""
-
-import contextlib
-import logging
-import sys
-import traceback
-
-from openstack_dashboard.openstack.common.gettextutils import _
-
-
-@contextlib.contextmanager
-def save_and_reraise_exception():
- """Save current exception, run some code and then re-raise.
-
- In some cases the exception context can be cleared, resulting in None
- being attempted to be re-raised after an exception handler is run. This
- can happen when eventlet switches greenthreads or when running an
- exception handler, code raises and catches an exception. In both
- cases the exception context will be cleared.
-
- To work around this, we save the exception state, run handler code, and
- then re-raise the original exception. If another exception occurs, the
- saved exception is logged and the new exception is re-raised.
- """
- type_, value, tb = sys.exc_info()
- try:
- yield
- except Exception:
- logging.error(_('Original exception being dropped: %s'),
- traceback.format_exception(type_, value, tb))
- raise
- raise type_, value, tb
diff --git a/openstack_dashboard/openstack/common/gettextutils.py b/openstack_dashboard/openstack/common/gettextutils.py
deleted file mode 100644
index 56a877f7..00000000
--- a/openstack_dashboard/openstack/common/gettextutils.py
+++ /dev/null
@@ -1,226 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Red Hat, Inc.
-# All Rights Reserved.
-# Copyright 2013 IBM Corp.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-gettext for openstack-common modules.
-
-Usual usage in an openstack.common module:
-
- from openstack_dashboard.openstack.common.gettextutils import _
-"""
-
-import copy
-import gettext
-import logging.handlers
-import os
-import UserString
-
-_localedir = os.environ.get('openstack_dashboard'.upper() + '_LOCALEDIR')
-_t = gettext.translation('openstack_dashboard', localedir=_localedir, fallback=True)
-
-
-def _(msg):
- return _t.ugettext(msg)
-
-
-def install(domain):
- """Install a _() function using the given translation domain.
-
- Given a translation domain, install a _() function using gettext's
- install() function.
-
- The main difference from gettext.install() is that we allow
- overriding the default localedir (e.g. /usr/share/locale) using
- a translation-domain-specific environment variable (e.g.
- NOVA_LOCALEDIR).
- """
- gettext.install(domain,
- localedir=os.environ.get(domain.upper() + '_LOCALEDIR'),
- unicode=True)
-
-
-"""
-Lazy gettext functionality.
-
-The following is an attempt to introduce a deferred way
-to do translations on messages in OpenStack. We attempt to
-override the standard _() function and % (format string) operation
-to build Message objects that can later be translated when we have
-more information. Also included is an example LogHandler that
-translates Messages to an associated locale, effectively allowing
-many logs, each with their own locale.
-"""
-
-
-def get_lazy_gettext(domain):
- """Assemble and return a lazy gettext function for a given domain.
-
- Factory method for a project/module to get a lazy gettext function
- for its own translation domain (i.e. nova, glance, cinder, etc.)
- """
-
- def _lazy_gettext(msg):
- """
- Create and return a Message object encapsulating a string
- so that we can translate it later when needed.
- """
- return Message(msg, domain)
-
- return _lazy_gettext
-
-
-class Message(UserString.UserString, object):
- """Class used to encapsulate translatable messages."""
- def __init__(self, msg, domain):
- # _msg is the gettext msgid and should never change
- self._msg = msg
- self._left_extra_msg = ''
- self._right_extra_msg = ''
- self.params = None
- self.locale = None
- self.domain = domain
-
- @property
- def data(self):
- # NOTE(mrodden): this should always resolve to a unicode string
- # that best represents the state of the message currently
-
- localedir = os.environ.get(self.domain.upper() + '_LOCALEDIR')
- if self.locale:
- lang = gettext.translation(self.domain,
- localedir=localedir,
- languages=[self.locale],
- fallback=True)
- else:
- # use system locale for translations
- lang = gettext.translation(self.domain,
- localedir=localedir,
- fallback=True)
-
- full_msg = (self._left_extra_msg +
- lang.ugettext(self._msg) +
- self._right_extra_msg)
-
- if self.params is not None:
- full_msg = full_msg % self.params
-
- return unicode(full_msg)
-
- def _save_parameters(self, other):
- # we check for None later to see if
- # we actually have parameters to inject,
- # so encapsulate if our parameter is actually None
- if other is None:
- self.params = (other, )
- else:
- self.params = copy.deepcopy(other)
-
- return self
-
- # overrides to be more string-like
- def __unicode__(self):
- return self.data
-
- def __str__(self):
- return self.data.encode('utf-8')
-
- def __getstate__(self):
- to_copy = ['_msg', '_right_extra_msg', '_left_extra_msg',
- 'domain', 'params', 'locale']
- new_dict = self.__dict__.fromkeys(to_copy)
- for attr in to_copy:
- new_dict[attr] = copy.deepcopy(self.__dict__[attr])
-
- return new_dict
-
- def __setstate__(self, state):
- for (k, v) in state.items():
- setattr(self, k, v)
-
- # operator overloads
- def __add__(self, other):
- copied = copy.deepcopy(self)
- copied._right_extra_msg += other.__str__()
- return copied
-
- def __radd__(self, other):
- copied = copy.deepcopy(self)
- copied._left_extra_msg += other.__str__()
- return copied
-
- def __mod__(self, other):
- # do a format string to catch and raise
- # any possible KeyErrors from missing parameters
- self.data % other
- copied = copy.deepcopy(self)
- return copied._save_parameters(other)
-
- def __mul__(self, other):
- return self.data * other
-
- def __rmul__(self, other):
- return other * self.data
-
- def __getitem__(self, key):
- return self.data[key]
-
- def __getslice__(self, start, end):
- return self.data.__getslice__(start, end)
-
- def __getattribute__(self, name):
- # NOTE(mrodden): handle lossy operations that we can't deal with yet
- # These override the UserString implementation, since UserString
- # uses our __class__ attribute to try and build a new message
- # after running the inner data string through the operation.
- # At that point, we have lost the gettext message id and can just
- # safely resolve to a string instead.
- ops = ['capitalize', 'center', 'decode', 'encode',
- 'expandtabs', 'ljust', 'lstrip', 'replace', 'rjust', 'rstrip',
- 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
- if name in ops:
- return getattr(self.data, name)
- else:
- return UserString.UserString.__getattribute__(self, name)
-
-
-class LocaleHandler(logging.Handler):
- """Handler that can have a locale associated to translate Messages.
-
- A quick example of how to utilize the Message class above.
- LocaleHandler takes a locale and a target logging.Handler object
- to forward LogRecord objects to after translating the internal Message.
- """
-
- def __init__(self, locale, target):
- """
- Initialize a LocaleHandler
-
- :param locale: locale to use for translating messages
- :param target: logging.Handler object to forward
- LogRecord objects to after translation
- """
- logging.Handler.__init__(self)
- self.locale = locale
- self.target = target
-
- def emit(self, record):
- if isinstance(record.msg, Message):
- # set the locale and resolve to a string
- record.msg.locale = self.locale
-
- self.target.emit(record)
diff --git a/openstack_dashboard/openstack/common/importutils.py b/openstack_dashboard/openstack/common/importutils.py
deleted file mode 100644
index dbee3251..00000000
--- a/openstack_dashboard/openstack/common/importutils.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Import related utilities and helper functions.
-"""
-
-import sys
-import traceback
-
-
-def import_class(import_str):
- """Returns a class from a string including module and class."""
- mod_str, _sep, class_str = import_str.rpartition('.')
- try:
- __import__(mod_str)
- return getattr(sys.modules[mod_str], class_str)
- except (ValueError, AttributeError):
- raise ImportError('Class %s cannot be found (%s)' %
- (class_str,
- traceback.format_exception(*sys.exc_info())))
-
-
-def import_object(import_str, *args, **kwargs):
- """Import a class and return an instance of it."""
- return import_class(import_str)(*args, **kwargs)
-
-
-def import_object_ns(name_space, import_str, *args, **kwargs):
- """
- Import a class and return an instance of it, first by trying
- to find the class in a default namespace, then failing back to
- a full path if not found in the default namespace.
- """
- import_value = "%s.%s" % (name_space, import_str)
- try:
- return import_class(import_value)(*args, **kwargs)
- except ImportError:
- return import_class(import_str)(*args, **kwargs)
-
-
-def import_module(import_str):
- """Import a module."""
- __import__(import_str)
- return sys.modules[import_str]
-
-
-def try_import(import_str, default=None):
- """Try to import a module and if it fails return default."""
- try:
- return import_module(import_str)
- except ImportError:
- return default
diff --git a/openstack_dashboard/openstack/common/jsonutils.py b/openstack_dashboard/openstack/common/jsonutils.py
deleted file mode 100644
index 7a235932..00000000
--- a/openstack_dashboard/openstack/common/jsonutils.py
+++ /dev/null
@@ -1,169 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2011 Justin Santa Barbara
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-'''
-JSON related utilities.
-
-This module provides a few things:
-
- 1) A handy function for getting an object down to something that can be
- JSON serialized. See to_primitive().
-
- 2) Wrappers around loads() and dumps(). The dumps() wrapper will
- automatically use to_primitive() for you if needed.
-
- 3) This sets up anyjson to use the loads() and dumps() wrappers if anyjson
- is available.
-'''
-
-
-import datetime
-import functools
-import inspect
-import itertools
-import json
-import types
-import xmlrpclib
-
-import six
-
-from openstack_dashboard.openstack.common import timeutils
-
-
-_nasty_type_tests = [inspect.ismodule, inspect.isclass, inspect.ismethod,
- inspect.isfunction, inspect.isgeneratorfunction,
- inspect.isgenerator, inspect.istraceback, inspect.isframe,
- inspect.iscode, inspect.isbuiltin, inspect.isroutine,
- inspect.isabstract]
-
-_simple_types = (types.NoneType, int, basestring, bool, float, long)
-
-
-def to_primitive(value, convert_instances=False, convert_datetime=True,
- level=0, max_depth=3):
- """Convert a complex object into primitives.
-
- Handy for JSON serialization. We can optionally handle instances,
- but since this is a recursive function, we could have cyclical
- data structures.
-
- To handle cyclical data structures we could track the actual objects
- visited in a set, but not all objects are hashable. Instead we just
- track the depth of the object inspections and don't go too deep.
-
- Therefore, convert_instances=True is lossy ... be aware.
-
- """
- # handle obvious types first - order of basic types determined by running
- # full tests on nova project, resulting in the following counts:
- # 572754 <type 'NoneType'>
- # 460353 <type 'int'>
- # 379632 <type 'unicode'>
- # 274610 <type 'str'>
- # 199918 <type 'dict'>
- # 114200 <type 'datetime.datetime'>
- # 51817 <type 'bool'>
- # 26164 <type 'list'>
- # 6491 <type 'float'>
- # 283 <type 'tuple'>
- # 19 <type 'long'>
- if isinstance(value, _simple_types):
- return value
-
- if isinstance(value, datetime.datetime):
- if convert_datetime:
- return timeutils.strtime(value)
- else:
- return value
-
- # value of itertools.count doesn't get caught by nasty_type_tests
- # and results in infinite loop when list(value) is called.
- if type(value) == itertools.count:
- return six.text_type(value)
-
- # FIXME(vish): Workaround for LP bug 852095. Without this workaround,
- # tests that raise an exception in a mocked method that
- # has a @wrap_exception with a notifier will fail. If
- # we up the dependency to 0.5.4 (when it is released) we
- # can remove this workaround.
- if getattr(value, '__module__', None) == 'mox':
- return 'mock'
-
- if level > max_depth:
- return '?'
-
- # The try block may not be necessary after the class check above,
- # but just in case ...
- try:
- recursive = functools.partial(to_primitive,
- convert_instances=convert_instances,
- convert_datetime=convert_datetime,
- level=level,
- max_depth=max_depth)
- if isinstance(value, dict):
- return dict((k, recursive(v)) for k, v in value.iteritems())
- elif isinstance(value, (list, tuple)):
- return [recursive(lv) for lv in value]
-
- # It's not clear why xmlrpclib created their own DateTime type, but
- # for our purposes, make it a datetime type which is explicitly
- # handled
- if isinstance(value, xmlrpclib.DateTime):
- value = datetime.datetime(*tuple(value.timetuple())[:6])
-
- if convert_datetime and isinstance(value, datetime.datetime):
- return timeutils.strtime(value)
- elif hasattr(value, 'iteritems'):
- return recursive(dict(value.iteritems()), level=level + 1)
- elif hasattr(value, '__iter__'):
- return recursive(list(value))
- elif convert_instances and hasattr(value, '__dict__'):
- # Likely an instance of something. Watch for cycles.
- # Ignore class member vars.
- return recursive(value.__dict__, level=level + 1)
- else:
- if any(test(value) for test in _nasty_type_tests):
- return six.text_type(value)
- return value
- except TypeError:
- # Class objects are tricky since they may define something like
- # __iter__ defined but it isn't callable as list().
- return six.text_type(value)
-
-
-def dumps(value, default=to_primitive, **kwargs):
- return json.dumps(value, default=default, **kwargs)
-
-
-def loads(s):
- return json.loads(s)
-
-
-def load(s):
- return json.load(s)
-
-
-try:
- import anyjson
-except ImportError:
- pass
-else:
- anyjson._modules.append((__name__, 'dumps', TypeError,
- 'loads', ValueError, 'load'))
- anyjson.force_implementation(__name__)
diff --git a/openstack_dashboard/openstack/common/local.py b/openstack_dashboard/openstack/common/local.py
deleted file mode 100644
index f1bfc824..00000000
--- a/openstack_dashboard/openstack/common/local.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Greenthread local storage of variables using weak references"""
-
-import weakref
-
-from eventlet import corolocal
-
-
-class WeakLocal(corolocal.local):
- def __getattribute__(self, attr):
- rval = corolocal.local.__getattribute__(self, attr)
- if rval:
- # NOTE(mikal): this bit is confusing. What is stored is a weak
- # reference, not the value itself. We therefore need to lookup
- # the weak reference and return the inner value here.
- rval = rval()
- return rval
-
- def __setattr__(self, attr, value):
- value = weakref.ref(value)
- return corolocal.local.__setattr__(self, attr, value)
-
-
-# NOTE(mikal): the name "store" should be deprecated in the future
-store = WeakLocal()
-
-# A "weak" store uses weak references and allows an object to fall out of scope
-# when it falls out of scope in the code that uses the thread local storage. A
-# "strong" store will hold a reference to the object so that it never falls out
-# of scope.
-weak_store = WeakLocal()
-strong_store = corolocal.local
diff --git a/openstack_dashboard/openstack/common/log.py b/openstack_dashboard/openstack/common/log.py
deleted file mode 100644
index 6571eda9..00000000
--- a/openstack_dashboard/openstack/common/log.py
+++ /dev/null
@@ -1,558 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 OpenStack Foundation.
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Openstack logging handler.
-
-This module adds to logging functionality by adding the option to specify
-a context object when calling the various log methods. If the context object
-is not specified, default formatting is used. Additionally, an instance uuid
-may be passed as part of the log message, which is intended to make it easier
-for admins to find messages related to a specific instance.
-
-It also allows setting of formatting information through conf.
-
-"""
-
-import ConfigParser
-import cStringIO
-import inspect
-import itertools
-import logging
-import logging.config
-import logging.handlers
-import os
-import sys
-import traceback
-
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import importutils
-from openstack_dashboard.openstack.common import jsonutils
-from openstack_dashboard.openstack.common import local
-
-
-_DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
-
-common_cli_opts = [
- cfg.BoolOpt('debug',
- short='d',
- default=False,
- help='Print debugging output (set logging level to '
- 'DEBUG instead of default WARNING level).'),
- cfg.BoolOpt('verbose',
- short='v',
- default=False,
- help='Print more verbose output (set logging level to '
- 'INFO instead of default WARNING level).'),
-]
-
-logging_cli_opts = [
- cfg.StrOpt('log-config',
- metavar='PATH',
- help='If this option is specified, the logging configuration '
- 'file specified is used and overrides any other logging '
- 'options specified. Please see the Python logging module '
- 'documentation for details on logging configuration '
- 'files.'),
- cfg.StrOpt('log-format',
- default=None,
- metavar='FORMAT',
- help='A logging.Formatter log message format string which may '
- 'use any of the available logging.LogRecord attributes. '
- 'This option is deprecated. Please use '
- 'logging_context_format_string and '
- 'logging_default_format_string instead.'),
- cfg.StrOpt('log-date-format',
- default=_DEFAULT_LOG_DATE_FORMAT,
- metavar='DATE_FORMAT',
- help='Format string for %%(asctime)s in log records. '
- 'Default: %(default)s'),
- cfg.StrOpt('log-file',
- metavar='PATH',
- deprecated_name='logfile',
- help='(Optional) Name of log file to output to. '
- 'If no default is set, logging will go to stdout.'),
- cfg.StrOpt('log-dir',
- deprecated_name='logdir',
- help='(Optional) The base directory used for relative '
- '--log-file paths'),
- cfg.BoolOpt('use-syslog',
- default=False,
- help='Use syslog for logging.'),
- cfg.StrOpt('syslog-log-facility',
- default='LOG_USER',
- help='syslog facility to receive log lines')
-]
-
-generic_log_opts = [
- cfg.BoolOpt('use_stderr',
- default=True,
- help='Log output to standard error')
-]
-
-log_opts = [
- cfg.StrOpt('logging_context_format_string',
- default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
- '%(name)s [%(request_id)s %(user)s %(tenant)s] '
- '%(instance)s%(message)s',
- help='format string to use for log messages with context'),
- cfg.StrOpt('logging_default_format_string',
- default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
- '%(name)s [-] %(instance)s%(message)s',
- help='format string to use for log messages without context'),
- cfg.StrOpt('logging_debug_format_suffix',
- default='%(funcName)s %(pathname)s:%(lineno)d',
- help='data to append to log format when level is DEBUG'),
- cfg.StrOpt('logging_exception_prefix',
- default='%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s '
- '%(instance)s',
- help='prefix each line of exception output with this format'),
- cfg.ListOpt('default_log_levels',
- default=[
- 'amqplib=WARN',
- 'sqlalchemy=WARN',
- 'boto=WARN',
- 'suds=INFO',
- 'keystone=INFO',
- 'eventlet.wsgi.server=WARN'
- ],
- help='list of logger=LEVEL pairs'),
- cfg.BoolOpt('publish_errors',
- default=False,
- help='publish error events'),
- cfg.BoolOpt('fatal_deprecations',
- default=False,
- help='make deprecations fatal'),
-
- # NOTE(mikal): there are two options here because sometimes we are handed
- # a full instance (and could include more information), and other times we
- # are just handed a UUID for the instance.
- cfg.StrOpt('instance_format',
- default='[instance: %(uuid)s] ',
- help='If an instance is passed with the log message, format '
- 'it like this'),
- cfg.StrOpt('instance_uuid_format',
- default='[instance: %(uuid)s] ',
- help='If an instance UUID is passed with the log message, '
- 'format it like this'),
-]
-
-CONF = cfg.CONF
-CONF.register_cli_opts(common_cli_opts)
-CONF.register_cli_opts(logging_cli_opts)
-CONF.register_opts(generic_log_opts)
-CONF.register_opts(log_opts)
-
-# our new audit level
-# NOTE(jkoelker) Since we synthesized an audit level, make the logging
-# module aware of it so it acts like other levels.
-logging.AUDIT = logging.INFO + 1
-logging.addLevelName(logging.AUDIT, 'AUDIT')
-
-
-try:
- NullHandler = logging.NullHandler
-except AttributeError: # NOTE(jkoelker) NullHandler added in Python 2.7
- class NullHandler(logging.Handler):
- def handle(self, record):
- pass
-
- def emit(self, record):
- pass
-
- def createLock(self):
- self.lock = None
-
-
-def _dictify_context(context):
- if context is None:
- return None
- if not isinstance(context, dict) and getattr(context, 'to_dict', None):
- context = context.to_dict()
- return context
-
-
-def _get_binary_name():
- return os.path.basename(inspect.stack()[-1][1])
-
-
-def _get_log_file_path(binary=None):
- logfile = CONF.log_file
- logdir = CONF.log_dir
-
- if logfile and not logdir:
- return logfile
-
- if logfile and logdir:
- return os.path.join(logdir, logfile)
-
- if logdir:
- binary = binary or _get_binary_name()
- return '%s.log' % (os.path.join(logdir, binary),)
-
-
-class BaseLoggerAdapter(logging.LoggerAdapter):
-
- def audit(self, msg, *args, **kwargs):
- self.log(logging.AUDIT, msg, *args, **kwargs)
-
-
-class LazyAdapter(BaseLoggerAdapter):
- def __init__(self, name='unknown', version='unknown'):
- self._logger = None
- self.extra = {}
- self.name = name
- self.version = version
-
- @property
- def logger(self):
- if not self._logger:
- self._logger = getLogger(self.name, self.version)
- return self._logger
-
-
-class ContextAdapter(BaseLoggerAdapter):
- warn = logging.LoggerAdapter.warning
-
- def __init__(self, logger, project_name, version_string):
- self.logger = logger
- self.project = project_name
- self.version = version_string
-
- @property
- def handlers(self):
- return self.logger.handlers
-
- def deprecated(self, msg, *args, **kwargs):
- stdmsg = _("Deprecated: %s") % msg
- if CONF.fatal_deprecations:
- self.critical(stdmsg, *args, **kwargs)
- raise DeprecatedConfig(msg=stdmsg)
- else:
- self.warn(stdmsg, *args, **kwargs)
-
- def process(self, msg, kwargs):
- if 'extra' not in kwargs:
- kwargs['extra'] = {}
- extra = kwargs['extra']
-
- context = kwargs.pop('context', None)
- if not context:
- context = getattr(local.store, 'context', None)
- if context:
- extra.update(_dictify_context(context))
-
- instance = kwargs.pop('instance', None)
- instance_extra = ''
- if instance:
- instance_extra = CONF.instance_format % instance
- else:
- instance_uuid = kwargs.pop('instance_uuid', None)
- if instance_uuid:
- instance_extra = (CONF.instance_uuid_format
- % {'uuid': instance_uuid})
- extra.update({'instance': instance_extra})
-
- extra.update({"project": self.project})
- extra.update({"version": self.version})
- extra['extra'] = extra.copy()
- return msg, kwargs
-
-
-class JSONFormatter(logging.Formatter):
- def __init__(self, fmt=None, datefmt=None):
- # NOTE(jkoelker) we ignore the fmt argument, but its still there
- # since logging.config.fileConfig passes it.
- self.datefmt = datefmt
-
- def formatException(self, ei, strip_newlines=True):
- lines = traceback.format_exception(*ei)
- if strip_newlines:
- lines = [itertools.ifilter(
- lambda x: x,
- line.rstrip().splitlines()) for line in lines]
- lines = list(itertools.chain(*lines))
- return lines
-
- def format(self, record):
- message = {'message': record.getMessage(),
- 'asctime': self.formatTime(record, self.datefmt),
- 'name': record.name,
- 'msg': record.msg,
- 'args': record.args,
- 'levelname': record.levelname,
- 'levelno': record.levelno,
- 'pathname': record.pathname,
- 'filename': record.filename,
- 'module': record.module,
- 'lineno': record.lineno,
- 'funcname': record.funcName,
- 'created': record.created,
- 'msecs': record.msecs,
- 'relative_created': record.relativeCreated,
- 'thread': record.thread,
- 'thread_name': record.threadName,
- 'process_name': record.processName,
- 'process': record.process,
- 'traceback': None}
-
- if hasattr(record, 'extra'):
- message['extra'] = record.extra
-
- if record.exc_info:
- message['traceback'] = self.formatException(record.exc_info)
-
- return jsonutils.dumps(message)
-
-
-def _create_logging_excepthook(product_name):
- def logging_excepthook(type, value, tb):
- extra = {}
- if CONF.verbose:
- extra['exc_info'] = (type, value, tb)
- getLogger(product_name).critical(str(value), **extra)
- return logging_excepthook
-
-
-class LogConfigError(Exception):
-
- message = _('Error loading logging config %(log_config)s: %(err_msg)s')
-
- def __init__(self, log_config, err_msg):
- self.log_config = log_config
- self.err_msg = err_msg
-
- def __str__(self):
- return self.message % dict(log_config=self.log_config,
- err_msg=self.err_msg)
-
-
-def _load_log_config(log_config):
- try:
- logging.config.fileConfig(log_config)
- except ConfigParser.Error as exc:
- raise LogConfigError(log_config, str(exc))
-
-
-def setup(product_name):
- """Setup logging."""
- if CONF.log_config:
- _load_log_config(CONF.log_config)
- else:
- _setup_logging_from_conf()
- sys.excepthook = _create_logging_excepthook(product_name)
-
-
-def set_defaults(logging_context_format_string):
- cfg.set_defaults(log_opts,
- logging_context_format_string=
- logging_context_format_string)
-
-
-def _find_facility_from_conf():
- facility_names = logging.handlers.SysLogHandler.facility_names
- facility = getattr(logging.handlers.SysLogHandler,
- CONF.syslog_log_facility,
- None)
-
- if facility is None and CONF.syslog_log_facility in facility_names:
- facility = facility_names.get(CONF.syslog_log_facility)
-
- if facility is None:
- valid_facilities = facility_names.keys()
- consts = ['LOG_AUTH', 'LOG_AUTHPRIV', 'LOG_CRON', 'LOG_DAEMON',
- 'LOG_FTP', 'LOG_KERN', 'LOG_LPR', 'LOG_MAIL', 'LOG_NEWS',
- 'LOG_AUTH', 'LOG_SYSLOG', 'LOG_USER', 'LOG_UUCP',
- 'LOG_LOCAL0', 'LOG_LOCAL1', 'LOG_LOCAL2', 'LOG_LOCAL3',
- 'LOG_LOCAL4', 'LOG_LOCAL5', 'LOG_LOCAL6', 'LOG_LOCAL7']
- valid_facilities.extend(consts)
- raise TypeError(_('syslog facility must be one of: %s') %
- ', '.join("'%s'" % fac
- for fac in valid_facilities))
-
- return facility
-
-
-def _setup_logging_from_conf():
- log_root = getLogger(None).logger
- for handler in log_root.handlers:
- log_root.removeHandler(handler)
-
- if CONF.use_syslog:
- facility = _find_facility_from_conf()
- syslog = logging.handlers.SysLogHandler(address='/dev/log',
- facility=facility)
- log_root.addHandler(syslog)
-
- logpath = _get_log_file_path()
- if logpath:
- filelog = logging.handlers.WatchedFileHandler(logpath)
- log_root.addHandler(filelog)
-
- if CONF.use_stderr:
- streamlog = ColorHandler()
- log_root.addHandler(streamlog)
-
- elif not CONF.log_file:
- # pass sys.stdout as a positional argument
- # python2.6 calls the argument strm, in 2.7 it's stream
- streamlog = logging.StreamHandler(sys.stdout)
- log_root.addHandler(streamlog)
-
- if CONF.publish_errors:
- handler = importutils.import_object(
- "openstack_dashboard.openstack.common.log_handler.PublishErrorsHandler",
- logging.ERROR)
- log_root.addHandler(handler)
-
- datefmt = CONF.log_date_format
- for handler in log_root.handlers:
- # NOTE(alaski): CONF.log_format overrides everything currently. This
- # should be deprecated in favor of context aware formatting.
- if CONF.log_format:
- handler.setFormatter(logging.Formatter(fmt=CONF.log_format,
- datefmt=datefmt))
- log_root.info('Deprecated: log_format is now deprecated and will '
- 'be removed in the next release')
- else:
- handler.setFormatter(ContextFormatter(datefmt=datefmt))
-
- if CONF.debug:
- log_root.setLevel(logging.DEBUG)
- elif CONF.verbose:
- log_root.setLevel(logging.INFO)
- else:
- log_root.setLevel(logging.WARNING)
-
- for pair in CONF.default_log_levels:
- mod, _sep, level_name = pair.partition('=')
- level = logging.getLevelName(level_name)
- logger = logging.getLogger(mod)
- logger.setLevel(level)
-
-_loggers = {}
-
-
-def getLogger(name='unknown', version='unknown'):
- if name not in _loggers:
- _loggers[name] = ContextAdapter(logging.getLogger(name),
- name,
- version)
- return _loggers[name]
-
-
-def getLazyLogger(name='unknown', version='unknown'):
- """
- create a pass-through logger that does not create the real logger
- until it is really needed and delegates all calls to the real logger
- once it is created
- """
- return LazyAdapter(name, version)
-
-
-class WritableLogger(object):
- """A thin wrapper that responds to `write` and logs."""
-
- def __init__(self, logger, level=logging.INFO):
- self.logger = logger
- self.level = level
-
- def write(self, msg):
- self.logger.log(self.level, msg)
-
-
-class ContextFormatter(logging.Formatter):
- """A context.RequestContext aware formatter configured through flags.
-
- The flags used to set format strings are: logging_context_format_string
- and logging_default_format_string. You can also specify
- logging_debug_format_suffix to append extra formatting if the log level is
- debug.
-
- For information about what variables are available for the formatter see:
- http://docs.python.org/library/logging.html#formatter
-
- """
-
- def format(self, record):
- """Uses contextstring if request_id is set, otherwise default."""
- # NOTE(sdague): default the fancier formating params
- # to an empty string so we don't throw an exception if
- # they get used
- for key in ('instance', 'color'):
- if key not in record.__dict__:
- record.__dict__[key] = ''
-
- if record.__dict__.get('request_id', None):
- self._fmt = CONF.logging_context_format_string
- else:
- self._fmt = CONF.logging_default_format_string
-
- if (record.levelno == logging.DEBUG and
- CONF.logging_debug_format_suffix):
- self._fmt += " " + CONF.logging_debug_format_suffix
-
- # Cache this on the record, Logger will respect our formated copy
- if record.exc_info:
- record.exc_text = self.formatException(record.exc_info, record)
- return logging.Formatter.format(self, record)
-
- def formatException(self, exc_info, record=None):
- """Format exception output with CONF.logging_exception_prefix."""
- if not record:
- return logging.Formatter.formatException(self, exc_info)
-
- stringbuffer = cStringIO.StringIO()
- traceback.print_exception(exc_info[0], exc_info[1], exc_info[2],
- None, stringbuffer)
- lines = stringbuffer.getvalue().split('\n')
- stringbuffer.close()
-
- if CONF.logging_exception_prefix.find('%(asctime)') != -1:
- record.asctime = self.formatTime(record, self.datefmt)
-
- formatted_lines = []
- for line in lines:
- pl = CONF.logging_exception_prefix % record.__dict__
- fl = '%s%s' % (pl, line)
- formatted_lines.append(fl)
- return '\n'.join(formatted_lines)
-
-
-class ColorHandler(logging.StreamHandler):
- LEVEL_COLORS = {
- logging.DEBUG: '\033[00;32m', # GREEN
- logging.INFO: '\033[00;36m', # CYAN
- logging.AUDIT: '\033[01;36m', # BOLD CYAN
- logging.WARN: '\033[01;33m', # BOLD YELLOW
- logging.ERROR: '\033[01;31m', # BOLD RED
- logging.CRITICAL: '\033[01;31m', # BOLD RED
- }
-
- def format(self, record):
- record.color = self.LEVEL_COLORS[record.levelno]
- return logging.StreamHandler.format(self, record)
-
-
-class DeprecatedConfig(Exception):
- message = _("Fatal call to deprecated config: %(msg)s")
-
- def __init__(self, msg):
- super(Exception, self).__init__(self.message % dict(msg=msg))
diff --git a/openstack_dashboard/openstack/common/loopingcall.py b/openstack_dashboard/openstack/common/loopingcall.py
deleted file mode 100644
index d44f2412..00000000
--- a/openstack_dashboard/openstack/common/loopingcall.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2011 Justin Santa Barbara
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import sys
-
-from eventlet import event
-from eventlet import greenthread
-
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common import timeutils
-
-LOG = logging.getLogger(__name__)
-
-
-class LoopingCallDone(Exception):
- """Exception to break out and stop a LoopingCall.
-
- The poll-function passed to LoopingCall can raise this exception to
- break out of the loop normally. This is somewhat analogous to
- StopIteration.
-
- An optional return-value can be included as the argument to the exception;
- this return-value will be returned by LoopingCall.wait()
-
- """
-
- def __init__(self, retvalue=True):
- """:param retvalue: Value that LoopingCall.wait() should return."""
- self.retvalue = retvalue
-
-
-class LoopingCallBase(object):
- def __init__(self, f=None, *args, **kw):
- self.args = args
- self.kw = kw
- self.f = f
- self._running = False
- self.done = None
-
- def stop(self):
- self._running = False
-
- def wait(self):
- return self.done.wait()
-
-
-class FixedIntervalLoopingCall(LoopingCallBase):
- """A fixed interval looping call."""
-
- def start(self, interval, initial_delay=None):
- self._running = True
- done = event.Event()
-
- def _inner():
- if initial_delay:
- greenthread.sleep(initial_delay)
-
- try:
- while self._running:
- start = timeutils.utcnow()
- self.f(*self.args, **self.kw)
- end = timeutils.utcnow()
- if not self._running:
- break
- delay = interval - timeutils.delta_seconds(start, end)
- if delay <= 0:
- LOG.warn(_('task run outlasted interval by %s sec') %
- -delay)
- greenthread.sleep(delay if delay > 0 else 0)
- except LoopingCallDone as e:
- self.stop()
- done.send(e.retvalue)
- except Exception:
- LOG.exception(_('in fixed duration looping call'))
- done.send_exception(*sys.exc_info())
- return
- else:
- done.send(True)
-
- self.done = done
-
- greenthread.spawn_n(_inner)
- return self.done
-
-
-# TODO(mikal): this class name is deprecated in Havana and should be removed
-# in the I release
-LoopingCall = FixedIntervalLoopingCall
-
-
-class DynamicLoopingCall(LoopingCallBase):
- """A looping call which sleeps until the next known event.
-
- The function called should return how long to sleep for before being
- called again.
- """
-
- def start(self, initial_delay=None, periodic_interval_max=None):
- self._running = True
- done = event.Event()
-
- def _inner():
- if initial_delay:
- greenthread.sleep(initial_delay)
-
- try:
- while self._running:
- idle = self.f(*self.args, **self.kw)
- if not self._running:
- break
-
- if periodic_interval_max is not None:
- idle = min(idle, periodic_interval_max)
- LOG.debug(_('Dynamic looping call sleeping for %.02f '
- 'seconds'), idle)
- greenthread.sleep(idle)
- except LoopingCallDone as e:
- self.stop()
- done.send(e.retvalue)
- except Exception:
- LOG.exception(_('in dynamic looping call'))
- done.send_exception(*sys.exc_info())
- return
- else:
- done.send(True)
-
- self.done = done
-
- greenthread.spawn(_inner)
- return self.done
diff --git a/openstack_dashboard/openstack/common/network_utils.py b/openstack_dashboard/openstack/common/network_utils.py
deleted file mode 100644
index 00c982e8..00000000
--- a/openstack_dashboard/openstack/common/network_utils.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Network-related utilities and helper functions.
-"""
-
-from openstack_dashboard.openstack.common import log as logging
-
-
-LOG = logging.getLogger(__name__)
-
-
-def parse_host_port(address, default_port=None):
- """
- Interpret a string as a host:port pair.
- An IPv6 address MUST be escaped if accompanied by a port,
- because otherwise ambiguity ensues: 2001:db8:85a3::8a2e:370:7334
- means both [2001:db8:85a3::8a2e:370:7334] and
- [2001:db8:85a3::8a2e:370]:7334.
-
- >>> parse_host_port('server01:80')
- ('server01', 80)
- >>> parse_host_port('server01')
- ('server01', None)
- >>> parse_host_port('server01', default_port=1234)
- ('server01', 1234)
- >>> parse_host_port('[::1]:80')
- ('::1', 80)
- >>> parse_host_port('[::1]')
- ('::1', None)
- >>> parse_host_port('[::1]', default_port=1234)
- ('::1', 1234)
- >>> parse_host_port('2001:db8:85a3::8a2e:370:7334', default_port=1234)
- ('2001:db8:85a3::8a2e:370:7334', 1234)
-
- """
- if address[0] == '[':
- # Escaped ipv6
- _host, _port = address[1:].split(']')
- host = _host
- if ':' in _port:
- port = _port.split(':')[1]
- else:
- port = default_port
- else:
- if address.count(':') == 1:
- host, port = address.split(':')
- else:
- # 0 means ipv4, >1 means ipv6.
- # We prohibit unescaped ipv6 addresses with port.
- host = address
- port = default_port
-
- return (host, None if port is None else int(port))
diff --git a/openstack_dashboard/openstack/common/notifier/__init__.py b/openstack_dashboard/openstack/common/notifier/__init__.py
deleted file mode 100644
index 45c3b46a..00000000
--- a/openstack_dashboard/openstack/common/notifier/__init__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2011 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
diff --git a/openstack_dashboard/openstack/common/notifier/api.py b/openstack_dashboard/openstack/common/notifier/api.py
deleted file mode 100644
index 0b61cd23..00000000
--- a/openstack_dashboard/openstack/common/notifier/api.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# Copyright 2011 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import uuid
-
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common import context
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import importutils
-from openstack_dashboard.openstack.common import jsonutils
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common import timeutils
-
-
-LOG = logging.getLogger(__name__)
-
-notifier_opts = [
- cfg.MultiStrOpt('notification_driver',
- default=[],
- help='Driver or drivers to handle sending notifications'),
- cfg.StrOpt('default_notification_level',
- default='INFO',
- help='Default notification level for outgoing notifications'),
- cfg.StrOpt('default_publisher_id',
- default='$host',
- help='Default publisher_id for outgoing notifications'),
-]
-
-CONF = cfg.CONF
-CONF.register_opts(notifier_opts)
-
-WARN = 'WARN'
-INFO = 'INFO'
-ERROR = 'ERROR'
-CRITICAL = 'CRITICAL'
-DEBUG = 'DEBUG'
-
-log_levels = (DEBUG, WARN, INFO, ERROR, CRITICAL)
-
-
-class BadPriorityException(Exception):
- pass
-
-
-def notify_decorator(name, fn):
- """Decorator for notify which is used from utils.monkey_patch().
-
- :param name: name of the function
- :param function: - object of the function
- :returns: function -- decorated function
-
- """
- def wrapped_func(*args, **kwarg):
- body = {}
- body['args'] = []
- body['kwarg'] = {}
- for arg in args:
- body['args'].append(arg)
- for key in kwarg:
- body['kwarg'][key] = kwarg[key]
-
- ctxt = context.get_context_from_function_and_args(fn, args, kwarg)
- notify(ctxt,
- CONF.default_publisher_id,
- name,
- CONF.default_notification_level,
- body)
- return fn(*args, **kwarg)
- return wrapped_func
-
-
-def publisher_id(service, host=None):
- if not host:
- host = CONF.host
- return "%s.%s" % (service, host)
-
-
-def notify(context, publisher_id, event_type, priority, payload):
- """Sends a notification using the specified driver
-
- :param publisher_id: the source worker_type.host of the message
- :param event_type: the literal type of event (ex. Instance Creation)
- :param priority: patterned after the enumeration of Python logging
- levels in the set (DEBUG, WARN, INFO, ERROR, CRITICAL)
- :param payload: A python dictionary of attributes
-
- Outgoing message format includes the above parameters, and appends the
- following:
-
- message_id
- a UUID representing the id for this notification
-
- timestamp
- the GMT timestamp the notification was sent at
-
- The composite message will be constructed as a dictionary of the above
- attributes, which will then be sent via the transport mechanism defined
- by the driver.
-
- Message example::
-
- {'message_id': str(uuid.uuid4()),
- 'publisher_id': 'compute.host1',
- 'timestamp': timeutils.utcnow(),
- 'priority': 'WARN',
- 'event_type': 'compute.create_instance',
- 'payload': {'instance_id': 12, ... }}
-
- """
- if priority not in log_levels:
- raise BadPriorityException(
- _('%s not in valid priorities') % priority)
-
- # Ensure everything is JSON serializable.
- payload = jsonutils.to_primitive(payload, convert_instances=True)
-
- msg = dict(message_id=str(uuid.uuid4()),
- publisher_id=publisher_id,
- event_type=event_type,
- priority=priority,
- payload=payload,
- timestamp=str(timeutils.utcnow()))
-
- for driver in _get_drivers():
- try:
- driver.notify(context, msg)
- except Exception as e:
- LOG.exception(_("Problem '%(e)s' attempting to "
- "send to notification system. "
- "Payload=%(payload)s")
- % dict(e=e, payload=payload))
-
-
-_drivers = None
-
-
-def _get_drivers():
- """Instantiate, cache, and return drivers based on the CONF."""
- global _drivers
- if _drivers is None:
- _drivers = {}
- for notification_driver in CONF.notification_driver:
- add_driver(notification_driver)
-
- return _drivers.values()
-
-
-def add_driver(notification_driver):
- """Add a notification driver at runtime."""
- # Make sure the driver list is initialized.
- _get_drivers()
- if isinstance(notification_driver, basestring):
- # Load and add
- try:
- driver = importutils.import_module(notification_driver)
- _drivers[notification_driver] = driver
- except ImportError:
- LOG.exception(_("Failed to load notifier %s. "
- "These notifications will not be sent.") %
- notification_driver)
- else:
- # Driver is already loaded; just add the object.
- _drivers[notification_driver] = notification_driver
-
-
-def _reset_drivers():
- """Used by unit tests to reset the drivers."""
- global _drivers
- _drivers = None
diff --git a/openstack_dashboard/openstack/common/notifier/log_notifier.py b/openstack_dashboard/openstack/common/notifier/log_notifier.py
deleted file mode 100644
index e2f2b619..00000000
--- a/openstack_dashboard/openstack/common/notifier/log_notifier.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2011 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common import jsonutils
-from openstack_dashboard.openstack.common import log as logging
-
-
-CONF = cfg.CONF
-
-
-def notify(_context, message):
- """Notifies the recipient of the desired event given the model.
-
- Log notifications using openstack's default logging system.
- """
-
- priority = message.get('priority',
- CONF.default_notification_level)
- priority = priority.lower()
- logger = logging.getLogger(
- 'openstack_dashboard.openstack.common.notification.%s' %
- message['event_type'])
- getattr(logger, priority)(jsonutils.dumps(message))
diff --git a/openstack_dashboard/openstack/common/notifier/no_op_notifier.py b/openstack_dashboard/openstack/common/notifier/no_op_notifier.py
deleted file mode 100644
index 13d946e3..00000000
--- a/openstack_dashboard/openstack/common/notifier/no_op_notifier.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2011 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-def notify(_context, message):
- """Notifies the recipient of the desired event given the model."""
- pass
diff --git a/openstack_dashboard/openstack/common/notifier/rpc_notifier.py b/openstack_dashboard/openstack/common/notifier/rpc_notifier.py
deleted file mode 100644
index b73e6287..00000000
--- a/openstack_dashboard/openstack/common/notifier/rpc_notifier.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2011 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common import context as req_context
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common import rpc
-
-LOG = logging.getLogger(__name__)
-
-notification_topic_opt = cfg.ListOpt(
- 'notification_topics', default=['notifications', ],
- help='AMQP topic used for openstack notifications')
-
-CONF = cfg.CONF
-CONF.register_opt(notification_topic_opt)
-
-
-def notify(context, message):
- """Sends a notification via RPC."""
- if not context:
- context = req_context.get_admin_context()
- priority = message.get('priority',
- CONF.default_notification_level)
- priority = priority.lower()
- for topic in CONF.notification_topics:
- topic = '%s.%s' % (topic, priority)
- try:
- rpc.notify(context, topic, message)
- except Exception:
- LOG.exception(_("Could not send notification to %(topic)s. "
- "Payload=%(message)s"), locals())
diff --git a/openstack_dashboard/openstack/common/notifier/rpc_notifier2.py b/openstack_dashboard/openstack/common/notifier/rpc_notifier2.py
deleted file mode 100644
index 79a8354d..00000000
--- a/openstack_dashboard/openstack/common/notifier/rpc_notifier2.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2011 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-'''messaging based notification driver, with message envelopes'''
-
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common import context as req_context
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common import rpc
-
-LOG = logging.getLogger(__name__)
-
-notification_topic_opt = cfg.ListOpt(
- 'topics', default=['notifications', ],
- help='AMQP topic(s) used for openstack notifications')
-
-opt_group = cfg.OptGroup(name='rpc_notifier2',
- title='Options for rpc_notifier2')
-
-CONF = cfg.CONF
-CONF.register_group(opt_group)
-CONF.register_opt(notification_topic_opt, opt_group)
-
-
-def notify(context, message):
- """Sends a notification via RPC."""
- if not context:
- context = req_context.get_admin_context()
- priority = message.get('priority',
- CONF.default_notification_level)
- priority = priority.lower()
- for topic in CONF.rpc_notifier2.topics:
- topic = '%s.%s' % (topic, priority)
- try:
- rpc.notify(context, topic, message, envelope=True)
- except Exception:
- LOG.exception(_("Could not send notification to %(topic)s. "
- "Payload=%(message)s"), locals())
diff --git a/openstack_dashboard/openstack/common/notifier/test_notifier.py b/openstack_dashboard/openstack/common/notifier/test_notifier.py
deleted file mode 100644
index 96c1746b..00000000
--- a/openstack_dashboard/openstack/common/notifier/test_notifier.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2011 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-NOTIFICATIONS = []
-
-
-def notify(_context, message):
- """Test notifier, stores notifications in memory for unittests."""
- NOTIFICATIONS.append(message)
diff --git a/openstack_dashboard/openstack/common/rpc/__init__.py b/openstack_dashboard/openstack/common/rpc/__init__.py
deleted file mode 100644
index cd2cbabf..00000000
--- a/openstack_dashboard/openstack/common/rpc/__init__.py
+++ /dev/null
@@ -1,307 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-# Copyright 2011 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-A remote procedure call (rpc) abstraction.
-
-For some wrappers that add message versioning to rpc, see:
- rpc.dispatcher
- rpc.proxy
-"""
-
-import inspect
-
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import importutils
-from openstack_dashboard.openstack.common import local
-from openstack_dashboard.openstack.common import log as logging
-
-
-LOG = logging.getLogger(__name__)
-
-
-rpc_opts = [
- cfg.StrOpt('rpc_backend',
- default='%s.impl_kombu' % __package__,
- help="The messaging module to use, defaults to kombu."),
- cfg.IntOpt('rpc_thread_pool_size',
- default=64,
- help='Size of RPC thread pool'),
- cfg.IntOpt('rpc_conn_pool_size',
- default=30,
- help='Size of RPC connection pool'),
- cfg.IntOpt('rpc_response_timeout',
- default=60,
- help='Seconds to wait for a response from call or multicall'),
- cfg.IntOpt('rpc_cast_timeout',
- default=30,
- help='Seconds to wait before a cast expires (TTL). '
- 'Only supported by impl_zmq.'),
- cfg.ListOpt('allowed_rpc_exception_modules',
- default=['openstack_dashboard.openstack.common.exception',
- 'nova.exception',
- 'cinder.exception',
- 'exceptions',
- ],
- help='Modules of exceptions that are permitted to be recreated'
- 'upon receiving exception data from an rpc call.'),
- cfg.BoolOpt('fake_rabbit',
- default=False,
- help='If passed, use a fake RabbitMQ provider'),
- cfg.StrOpt('control_exchange',
- default='openstack',
- help='AMQP exchange to connect to if using RabbitMQ or Qpid'),
-]
-
-CONF = cfg.CONF
-CONF.register_opts(rpc_opts)
-
-
-def set_defaults(control_exchange):
- cfg.set_defaults(rpc_opts,
- control_exchange=control_exchange)
-
-
-def create_connection(new=True):
- """Create a connection to the message bus used for rpc.
-
- For some example usage of creating a connection and some consumers on that
- connection, see nova.service.
-
- :param new: Whether or not to create a new connection. A new connection
- will be created by default. If new is False, the
- implementation is free to return an existing connection from a
- pool.
-
- :returns: An instance of openstack.common.rpc.common.Connection
- """
- return _get_impl().create_connection(CONF, new=new)
-
-
-def _check_for_lock():
- if not CONF.debug:
- return None
-
- if ((hasattr(local.strong_store, 'locks_held')
- and local.strong_store.locks_held)):
- stack = ' :: '.join([frame[3] for frame in inspect.stack()])
- LOG.warn(_('A RPC is being made while holding a lock. The locks '
- 'currently held are %(locks)s. This is probably a bug. '
- 'Please report it. Include the following: [%(stack)s].'),
- {'locks': local.strong_store.locks_held,
- 'stack': stack})
- return True
-
- return False
-
-
-def call(context, topic, msg, timeout=None, check_for_lock=False):
- """Invoke a remote method that returns something.
-
- :param context: Information that identifies the user that has made this
- request.
- :param topic: The topic to send the rpc message to. This correlates to the
- topic argument of
- openstack.common.rpc.common.Connection.create_consumer()
- and only applies when the consumer was created with
- fanout=False.
- :param msg: This is a dict in the form { "method" : "method_to_invoke",
- "args" : dict_of_kwargs }
- :param timeout: int, number of seconds to use for a response timeout.
- If set, this overrides the rpc_response_timeout option.
- :param check_for_lock: if True, a warning is emitted if a RPC call is made
- with a lock held.
-
- :returns: A dict from the remote method.
-
- :raises: openstack.common.rpc.common.Timeout if a complete response
- is not received before the timeout is reached.
- """
- if check_for_lock:
- _check_for_lock()
- return _get_impl().call(CONF, context, topic, msg, timeout)
-
-
-def cast(context, topic, msg):
- """Invoke a remote method that does not return anything.
-
- :param context: Information that identifies the user that has made this
- request.
- :param topic: The topic to send the rpc message to. This correlates to the
- topic argument of
- openstack.common.rpc.common.Connection.create_consumer()
- and only applies when the consumer was created with
- fanout=False.
- :param msg: This is a dict in the form { "method" : "method_to_invoke",
- "args" : dict_of_kwargs }
-
- :returns: None
- """
- return _get_impl().cast(CONF, context, topic, msg)
-
-
-def fanout_cast(context, topic, msg):
- """Broadcast a remote method invocation with no return.
-
- This method will get invoked on all consumers that were set up with this
- topic name and fanout=True.
-
- :param context: Information that identifies the user that has made this
- request.
- :param topic: The topic to send the rpc message to. This correlates to the
- topic argument of
- openstack.common.rpc.common.Connection.create_consumer()
- and only applies when the consumer was created with
- fanout=True.
- :param msg: This is a dict in the form { "method" : "method_to_invoke",
- "args" : dict_of_kwargs }
-
- :returns: None
- """
- return _get_impl().fanout_cast(CONF, context, topic, msg)
-
-
-def multicall(context, topic, msg, timeout=None, check_for_lock=False):
- """Invoke a remote method and get back an iterator.
-
- In this case, the remote method will be returning multiple values in
- separate messages, so the return values can be processed as the come in via
- an iterator.
-
- :param context: Information that identifies the user that has made this
- request.
- :param topic: The topic to send the rpc message to. This correlates to the
- topic argument of
- openstack.common.rpc.common.Connection.create_consumer()
- and only applies when the consumer was created with
- fanout=False.
- :param msg: This is a dict in the form { "method" : "method_to_invoke",
- "args" : dict_of_kwargs }
- :param timeout: int, number of seconds to use for a response timeout.
- If set, this overrides the rpc_response_timeout option.
- :param check_for_lock: if True, a warning is emitted if a RPC call is made
- with a lock held.
-
- :returns: An iterator. The iterator will yield a tuple (N, X) where N is
- an index that starts at 0 and increases by one for each value
- returned and X is the Nth value that was returned by the remote
- method.
-
- :raises: openstack.common.rpc.common.Timeout if a complete response
- is not received before the timeout is reached.
- """
- if check_for_lock:
- _check_for_lock()
- return _get_impl().multicall(CONF, context, topic, msg, timeout)
-
-
-def notify(context, topic, msg, envelope=False):
- """Send notification event.
-
- :param context: Information that identifies the user that has made this
- request.
- :param topic: The topic to send the notification to.
- :param msg: This is a dict of content of event.
- :param envelope: Set to True to enable message envelope for notifications.
-
- :returns: None
- """
- return _get_impl().notify(cfg.CONF, context, topic, msg, envelope)
-
-
-def cleanup():
- """Clean up resoruces in use by implementation.
-
- Clean up any resources that have been allocated by the RPC implementation.
- This is typically open connections to a messaging service. This function
- would get called before an application using this API exits to allow
- connections to get torn down cleanly.
-
- :returns: None
- """
- return _get_impl().cleanup()
-
-
-def cast_to_server(context, server_params, topic, msg):
- """Invoke a remote method that does not return anything.
-
- :param context: Information that identifies the user that has made this
- request.
- :param server_params: Connection information
- :param topic: The topic to send the notification to.
- :param msg: This is a dict in the form { "method" : "method_to_invoke",
- "args" : dict_of_kwargs }
-
- :returns: None
- """
- return _get_impl().cast_to_server(CONF, context, server_params, topic,
- msg)
-
-
-def fanout_cast_to_server(context, server_params, topic, msg):
- """Broadcast to a remote method invocation with no return.
-
- :param context: Information that identifies the user that has made this
- request.
- :param server_params: Connection information
- :param topic: The topic to send the notification to.
- :param msg: This is a dict in the form { "method" : "method_to_invoke",
- "args" : dict_of_kwargs }
-
- :returns: None
- """
- return _get_impl().fanout_cast_to_server(CONF, context, server_params,
- topic, msg)
-
-
-def queue_get_for(context, topic, host):
- """Get a queue name for a given topic + host.
-
- This function only works if this naming convention is followed on the
- consumer side, as well. For example, in nova, every instance of the
- nova-foo service calls create_consumer() for two topics:
-
- foo
- foo.<host>
-
- Messages sent to the 'foo' topic are distributed to exactly one instance of
- the nova-foo service. The services are chosen in a round-robin fashion.
- Messages sent to the 'foo.<host>' topic are sent to the nova-foo service on
- <host>.
- """
- return '%s.%s' % (topic, host) if host else topic
-
-
-_RPCIMPL = None
-
-
-def _get_impl():
- """Delay import of rpc_backend until configuration is loaded."""
- global _RPCIMPL
- if _RPCIMPL is None:
- try:
- _RPCIMPL = importutils.import_module(CONF.rpc_backend)
- except ImportError:
- # For backwards compatibility with older nova config.
- impl = CONF.rpc_backend.replace('nova.rpc',
- 'nova.openstack.common.rpc')
- _RPCIMPL = importutils.import_module(impl)
- return _RPCIMPL
diff --git a/openstack_dashboard/openstack/common/rpc/amqp.py b/openstack_dashboard/openstack/common/rpc/amqp.py
deleted file mode 100644
index c655c48d..00000000
--- a/openstack_dashboard/openstack/common/rpc/amqp.py
+++ /dev/null
@@ -1,678 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-# Copyright 2011 - 2012, Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Shared code between AMQP based openstack.common.rpc implementations.
-
-The code in this module is shared between the rpc implemenations based on AMQP.
-Specifically, this includes impl_kombu and impl_qpid. impl_carrot also uses
-AMQP, but is deprecated and predates this code.
-"""
-
-import collections
-import inspect
-import sys
-import uuid
-
-from eventlet import greenpool
-from eventlet import pools
-from eventlet import queue
-from eventlet import semaphore
-# TODO(pekowsk): Remove import cfg and below comment in Havana.
-# This import should no longer be needed when the amqp_rpc_single_reply_queue
-# option is removed.
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common import excutils
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import local
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common.rpc import common as rpc_common
-
-
-# TODO(pekowski): Remove this option in Havana.
-amqp_opts = [
- cfg.BoolOpt('amqp_rpc_single_reply_queue',
- default=False,
- help='Enable a fast single reply queue if using AMQP based '
- 'RPC like RabbitMQ or Qpid.'),
-]
-
-cfg.CONF.register_opts(amqp_opts)
-
-UNIQUE_ID = '_unique_id'
-LOG = logging.getLogger(__name__)
-
-
-class Pool(pools.Pool):
- """Class that implements a Pool of Connections."""
- def __init__(self, conf, connection_cls, *args, **kwargs):
- self.connection_cls = connection_cls
- self.conf = conf
- kwargs.setdefault("max_size", self.conf.rpc_conn_pool_size)
- kwargs.setdefault("order_as_stack", True)
- super(Pool, self).__init__(*args, **kwargs)
- self.reply_proxy = None
-
- # TODO(comstud): Timeout connections not used in a while
- def create(self):
- LOG.debug(_('Pool creating new connection'))
- return self.connection_cls(self.conf)
-
- def empty(self):
- while self.free_items:
- self.get().close()
- # Force a new connection pool to be created.
- # Note that this was added due to failing unit test cases. The issue
- # is the above "while loop" gets all the cached connections from the
- # pool and closes them, but never returns them to the pool, a pool
- # leak. The unit tests hang waiting for an item to be returned to the
- # pool. The unit tests get here via the teatDown() method. In the run
- # time code, it gets here via cleanup() and only appears in service.py
- # just before doing a sys.exit(), so cleanup() only happens once and
- # the leakage is not a problem.
- self.connection_cls.pool = None
-
-
-_pool_create_sem = semaphore.Semaphore()
-
-
-def get_connection_pool(conf, connection_cls):
- with _pool_create_sem:
- # Make sure only one thread tries to create the connection pool.
- if not connection_cls.pool:
- connection_cls.pool = Pool(conf, connection_cls)
- return connection_cls.pool
-
-
-class ConnectionContext(rpc_common.Connection):
- """The class that is actually returned to the caller of
- create_connection(). This is essentially a wrapper around
- Connection that supports 'with'. It can also return a new
- Connection, or one from a pool. The function will also catch
- when an instance of this class is to be deleted. With that
- we can return Connections to the pool on exceptions and so
- forth without making the caller be responsible for catching
- them. If possible the function makes sure to return a
- connection to the pool.
- """
-
- def __init__(self, conf, connection_pool, pooled=True, server_params=None):
- """Create a new connection, or get one from the pool."""
- self.connection = None
- self.conf = conf
- self.connection_pool = connection_pool
- if pooled:
- self.connection = connection_pool.get()
- else:
- self.connection = connection_pool.connection_cls(
- conf,
- server_params=server_params)
- self.pooled = pooled
-
- def __enter__(self):
- """When with ConnectionContext() is used, return self."""
- return self
-
- def _done(self):
- """If the connection came from a pool, clean it up and put it back.
- If it did not come from a pool, close it.
- """
- if self.connection:
- if self.pooled:
- # Reset the connection so it's ready for the next caller
- # to grab from the pool
- self.connection.reset()
- self.connection_pool.put(self.connection)
- else:
- try:
- self.connection.close()
- except Exception:
- pass
- self.connection = None
-
- def __exit__(self, exc_type, exc_value, tb):
- """End of 'with' statement. We're done here."""
- self._done()
-
- def __del__(self):
- """Caller is done with this connection. Make sure we cleaned up."""
- self._done()
-
- def close(self):
- """Caller is done with this connection."""
- self._done()
-
- def create_consumer(self, topic, proxy, fanout=False):
- self.connection.create_consumer(topic, proxy, fanout)
-
- def create_worker(self, topic, proxy, pool_name):
- self.connection.create_worker(topic, proxy, pool_name)
-
- def join_consumer_pool(self, callback, pool_name, topic, exchange_name):
- self.connection.join_consumer_pool(callback,
- pool_name,
- topic,
- exchange_name)
-
- def consume_in_thread(self):
- self.connection.consume_in_thread()
-
- def __getattr__(self, key):
- """Proxy all other calls to the Connection instance."""
- if self.connection:
- return getattr(self.connection, key)
- else:
- raise rpc_common.InvalidRPCConnectionReuse()
-
-
-class ReplyProxy(ConnectionContext):
- """Connection class for RPC replies / callbacks."""
- def __init__(self, conf, connection_pool):
- self._call_waiters = {}
- self._num_call_waiters = 0
- self._num_call_waiters_wrn_threshhold = 10
- self._reply_q = 'reply_' + uuid.uuid4().hex
- super(ReplyProxy, self).__init__(conf, connection_pool, pooled=False)
- self.declare_direct_consumer(self._reply_q, self._process_data)
- self.consume_in_thread()
-
- def _process_data(self, message_data):
- msg_id = message_data.pop('_msg_id', None)
- waiter = self._call_waiters.get(msg_id)
- if not waiter:
- LOG.warn(_('no calling threads waiting for msg_id : %(msg_id)s'
- ', message : %(data)s'), {'msg_id': msg_id,
- 'data': message_data})
- else:
- waiter.put(message_data)
-
- def add_call_waiter(self, waiter, msg_id):
- self._num_call_waiters += 1
- if self._num_call_waiters > self._num_call_waiters_wrn_threshhold:
- LOG.warn(_('Number of call waiters is greater than warning '
- 'threshhold: %d. There could be a MulticallProxyWaiter '
- 'leak.') % self._num_call_waiters_wrn_threshhold)
- self._num_call_waiters_wrn_threshhold *= 2
- self._call_waiters[msg_id] = waiter
-
- def del_call_waiter(self, msg_id):
- self._num_call_waiters -= 1
- del self._call_waiters[msg_id]
-
- def get_reply_q(self):
- return self._reply_q
-
-
-def msg_reply(conf, msg_id, reply_q, connection_pool, reply=None,
- failure=None, ending=False, log_failure=True):
- """Sends a reply or an error on the channel signified by msg_id.
-
- Failure should be a sys.exc_info() tuple.
-
- """
- with ConnectionContext(conf, connection_pool) as conn:
- if failure:
- failure = rpc_common.serialize_remote_exception(failure,
- log_failure)
-
- try:
- msg = {'result': reply, 'failure': failure}
- except TypeError:
- msg = {'result': dict((k, repr(v))
- for k, v in reply.__dict__.iteritems()),
- 'failure': failure}
- if ending:
- msg['ending'] = True
- _add_unique_id(msg)
- # If a reply_q exists, add the msg_id to the reply and pass the
- # reply_q to direct_send() to use it as the response queue.
- # Otherwise use the msg_id for backward compatibilty.
- if reply_q:
- msg['_msg_id'] = msg_id
- conn.direct_send(reply_q, rpc_common.serialize_msg(msg))
- else:
- conn.direct_send(msg_id, rpc_common.serialize_msg(msg))
-
-
-class RpcContext(rpc_common.CommonRpcContext):
- """Context that supports replying to a rpc.call."""
- def __init__(self, **kwargs):
- self.msg_id = kwargs.pop('msg_id', None)
- self.reply_q = kwargs.pop('reply_q', None)
- self.conf = kwargs.pop('conf')
- super(RpcContext, self).__init__(**kwargs)
-
- def deepcopy(self):
- values = self.to_dict()
- values['conf'] = self.conf
- values['msg_id'] = self.msg_id
- values['reply_q'] = self.reply_q
- return self.__class__(**values)
-
- def reply(self, reply=None, failure=None, ending=False,
- connection_pool=None, log_failure=True):
- if self.msg_id:
- msg_reply(self.conf, self.msg_id, self.reply_q, connection_pool,
- reply, failure, ending, log_failure)
- if ending:
- self.msg_id = None
-
-
-def unpack_context(conf, msg):
- """Unpack context from msg."""
- context_dict = {}
- for key in list(msg.keys()):
- # NOTE(vish): Some versions of python don't like unicode keys
- # in kwargs.
- key = str(key)
- if key.startswith('_context_'):
- value = msg.pop(key)
- context_dict[key[9:]] = value
- context_dict['msg_id'] = msg.pop('_msg_id', None)
- context_dict['reply_q'] = msg.pop('_reply_q', None)
- context_dict['conf'] = conf
- ctx = RpcContext.from_dict(context_dict)
- rpc_common._safe_log(LOG.debug, _('unpacked context: %s'), ctx.to_dict())
- return ctx
-
-
-def pack_context(msg, context):
- """Pack context into msg.
-
- Values for message keys need to be less than 255 chars, so we pull
- context out into a bunch of separate keys. If we want to support
- more arguments in rabbit messages, we may want to do the same
- for args at some point.
-
- """
- context_d = dict([('_context_%s' % key, value)
- for (key, value) in context.to_dict().iteritems()])
- msg.update(context_d)
-
-
-class _MsgIdCache(object):
- """This class checks any duplicate messages."""
-
- # NOTE: This value is considered can be a configuration item, but
- # it is not necessary to change its value in most cases,
- # so let this value as static for now.
- DUP_MSG_CHECK_SIZE = 16
-
- def __init__(self, **kwargs):
- self.prev_msgids = collections.deque([],
- maxlen=self.DUP_MSG_CHECK_SIZE)
-
- def check_duplicate_message(self, message_data):
- """AMQP consumers may read same message twice when exceptions occur
- before ack is returned. This method prevents doing it.
- """
- if UNIQUE_ID in message_data:
- msg_id = message_data[UNIQUE_ID]
- if msg_id not in self.prev_msgids:
- self.prev_msgids.append(msg_id)
- else:
- raise rpc_common.DuplicateMessageError(msg_id=msg_id)
-
-
-def _add_unique_id(msg):
- """Add unique_id for checking duplicate messages."""
- unique_id = uuid.uuid4().hex
- msg.update({UNIQUE_ID: unique_id})
- LOG.debug(_('UNIQUE_ID is %s.') % (unique_id))
-
-
-class _ThreadPoolWithWait(object):
- """Base class for a delayed invocation manager used by
- the Connection class to start up green threads
- to handle incoming messages.
- """
-
- def __init__(self, conf, connection_pool):
- self.pool = greenpool.GreenPool(conf.rpc_thread_pool_size)
- self.connection_pool = connection_pool
- self.conf = conf
-
- def wait(self):
- """Wait for all callback threads to exit."""
- self.pool.waitall()
-
-
-class CallbackWrapper(_ThreadPoolWithWait):
- """Wraps a straight callback to allow it to be invoked in a green
- thread.
- """
-
- def __init__(self, conf, callback, connection_pool):
- """
- :param conf: cfg.CONF instance
- :param callback: a callable (probably a function)
- :param connection_pool: connection pool as returned by
- get_connection_pool()
- """
- super(CallbackWrapper, self).__init__(
- conf=conf,
- connection_pool=connection_pool,
- )
- self.callback = callback
-
- def __call__(self, message_data):
- self.pool.spawn_n(self.callback, message_data)
-
-
-class ProxyCallback(_ThreadPoolWithWait):
- """Calls methods on a proxy object based on method and args."""
-
- def __init__(self, conf, proxy, connection_pool):
- super(ProxyCallback, self).__init__(
- conf=conf,
- connection_pool=connection_pool,
- )
- self.proxy = proxy
- self.msg_id_cache = _MsgIdCache()
-
- def __call__(self, message_data):
- """Consumer callback to call a method on a proxy object.
-
- Parses the message for validity and fires off a thread to call the
- proxy object method.
-
- Message data should be a dictionary with two keys:
- method: string representing the method to call
- args: dictionary of arg: value
-
- Example: {'method': 'echo', 'args': {'value': 42}}
-
- """
- # It is important to clear the context here, because at this point
- # the previous context is stored in local.store.context
- if hasattr(local.store, 'context'):
- del local.store.context
- rpc_common._safe_log(LOG.debug, _('received %s'), message_data)
- self.msg_id_cache.check_duplicate_message(message_data)
- ctxt = unpack_context(self.conf, message_data)
- method = message_data.get('method')
- args = message_data.get('args', {})
- version = message_data.get('version')
- namespace = message_data.get('namespace')
- if not method:
- LOG.warn(_('no method for message: %s') % message_data)
- ctxt.reply(_('No method for message: %s') % message_data,
- connection_pool=self.connection_pool)
- return
- self.pool.spawn_n(self._process_data, ctxt, version, method,
- namespace, args)
-
- def _process_data(self, ctxt, version, method, namespace, args):
- """Process a message in a new thread.
-
- If the proxy object we have has a dispatch method
- (see rpc.dispatcher.RpcDispatcher), pass it the version,
- method, and args and let it dispatch as appropriate. If not, use
- the old behavior of magically calling the specified method on the
- proxy we have here.
- """
- ctxt.update_store()
- try:
- rval = self.proxy.dispatch(ctxt, version, method, namespace,
- **args)
- # Check if the result was a generator
- if inspect.isgenerator(rval):
- for x in rval:
- ctxt.reply(x, None, connection_pool=self.connection_pool)
- else:
- ctxt.reply(rval, None, connection_pool=self.connection_pool)
- # This final None tells multicall that it is done.
- ctxt.reply(ending=True, connection_pool=self.connection_pool)
- except rpc_common.ClientException as e:
- LOG.debug(_('Expected exception during message handling (%s)') %
- e._exc_info[1])
- ctxt.reply(None, e._exc_info,
- connection_pool=self.connection_pool,
- log_failure=False)
- except Exception:
- # sys.exc_info() is deleted by LOG.exception().
- exc_info = sys.exc_info()
- LOG.error(_('Exception during message handling'),
- exc_info=exc_info)
- ctxt.reply(None, exc_info, connection_pool=self.connection_pool)
-
-
-class MulticallProxyWaiter(object):
- def __init__(self, conf, msg_id, timeout, connection_pool):
- self._msg_id = msg_id
- self._timeout = timeout or conf.rpc_response_timeout
- self._reply_proxy = connection_pool.reply_proxy
- self._done = False
- self._got_ending = False
- self._conf = conf
- self._dataqueue = queue.LightQueue()
- # Add this caller to the reply proxy's call_waiters
- self._reply_proxy.add_call_waiter(self, self._msg_id)
- self.msg_id_cache = _MsgIdCache()
-
- def put(self, data):
- self._dataqueue.put(data)
-
- def done(self):
- if self._done:
- return
- self._done = True
- # Remove this caller from reply proxy's call_waiters
- self._reply_proxy.del_call_waiter(self._msg_id)
-
- def _process_data(self, data):
- result = None
- self.msg_id_cache.check_duplicate_message(data)
- if data['failure']:
- failure = data['failure']
- result = rpc_common.deserialize_remote_exception(self._conf,
- failure)
- elif data.get('ending', False):
- self._got_ending = True
- else:
- result = data['result']
- return result
-
- def __iter__(self):
- """Return a result until we get a reply with an 'ending' flag."""
- if self._done:
- raise StopIteration
- while True:
- try:
- data = self._dataqueue.get(timeout=self._timeout)
- result = self._process_data(data)
- except queue.Empty:
- self.done()
- raise rpc_common.Timeout()
- except Exception:
- with excutils.save_and_reraise_exception():
- self.done()
- if self._got_ending:
- self.done()
- raise StopIteration
- if isinstance(result, Exception):
- self.done()
- raise result
- yield result
-
-
-#TODO(pekowski): Remove MulticallWaiter() in Havana.
-class MulticallWaiter(object):
- def __init__(self, conf, connection, timeout):
- self._connection = connection
- self._iterator = connection.iterconsume(timeout=timeout or
- conf.rpc_response_timeout)
- self._result = None
- self._done = False
- self._got_ending = False
- self._conf = conf
- self.msg_id_cache = _MsgIdCache()
-
- def done(self):
- if self._done:
- return
- self._done = True
- self._iterator.close()
- self._iterator = None
- self._connection.close()
-
- def __call__(self, data):
- """The consume() callback will call this. Store the result."""
- self.msg_id_cache.check_duplicate_message(data)
- if data['failure']:
- failure = data['failure']
- self._result = rpc_common.deserialize_remote_exception(self._conf,
- failure)
-
- elif data.get('ending', False):
- self._got_ending = True
- else:
- self._result = data['result']
-
- def __iter__(self):
- """Return a result until we get a 'None' response from consumer"""
- if self._done:
- raise StopIteration
- while True:
- try:
- self._iterator.next()
- except Exception:
- with excutils.save_and_reraise_exception():
- self.done()
- if self._got_ending:
- self.done()
- raise StopIteration
- result = self._result
- if isinstance(result, Exception):
- self.done()
- raise result
- yield result
-
-
-def create_connection(conf, new, connection_pool):
- """Create a connection."""
- return ConnectionContext(conf, connection_pool, pooled=not new)
-
-
-_reply_proxy_create_sem = semaphore.Semaphore()
-
-
-def multicall(conf, context, topic, msg, timeout, connection_pool):
- """Make a call that returns multiple times."""
- # TODO(pekowski): Remove all these comments in Havana.
- # For amqp_rpc_single_reply_queue = False,
- # Can't use 'with' for multicall, as it returns an iterator
- # that will continue to use the connection. When it's done,
- # connection.close() will get called which will put it back into
- # the pool
- # For amqp_rpc_single_reply_queue = True,
- # The 'with' statement is mandatory for closing the connection
- LOG.debug(_('Making synchronous call on %s ...'), topic)
- msg_id = uuid.uuid4().hex
- msg.update({'_msg_id': msg_id})
- LOG.debug(_('MSG_ID is %s') % (msg_id))
- _add_unique_id(msg)
- pack_context(msg, context)
-
- # TODO(pekowski): Remove this flag and the code under the if clause
- # in Havana.
- if not conf.amqp_rpc_single_reply_queue:
- conn = ConnectionContext(conf, connection_pool)
- wait_msg = MulticallWaiter(conf, conn, timeout)
- conn.declare_direct_consumer(msg_id, wait_msg)
- conn.topic_send(topic, rpc_common.serialize_msg(msg), timeout)
- else:
- with _reply_proxy_create_sem:
- if not connection_pool.reply_proxy:
- connection_pool.reply_proxy = ReplyProxy(conf, connection_pool)
- msg.update({'_reply_q': connection_pool.reply_proxy.get_reply_q()})
- wait_msg = MulticallProxyWaiter(conf, msg_id, timeout, connection_pool)
- with ConnectionContext(conf, connection_pool) as conn:
- conn.topic_send(topic, rpc_common.serialize_msg(msg), timeout)
- return wait_msg
-
-
-def call(conf, context, topic, msg, timeout, connection_pool):
- """Sends a message on a topic and wait for a response."""
- rv = multicall(conf, context, topic, msg, timeout, connection_pool)
- # NOTE(vish): return the last result from the multicall
- rv = list(rv)
- if not rv:
- return
- return rv[-1]
-
-
-def cast(conf, context, topic, msg, connection_pool):
- """Sends a message on a topic without waiting for a response."""
- LOG.debug(_('Making asynchronous cast on %s...'), topic)
- _add_unique_id(msg)
- pack_context(msg, context)
- with ConnectionContext(conf, connection_pool) as conn:
- conn.topic_send(topic, rpc_common.serialize_msg(msg))
-
-
-def fanout_cast(conf, context, topic, msg, connection_pool):
- """Sends a message on a fanout exchange without waiting for a response."""
- LOG.debug(_('Making asynchronous fanout cast...'))
- _add_unique_id(msg)
- pack_context(msg, context)
- with ConnectionContext(conf, connection_pool) as conn:
- conn.fanout_send(topic, rpc_common.serialize_msg(msg))
-
-
-def cast_to_server(conf, context, server_params, topic, msg, connection_pool):
- """Sends a message on a topic to a specific server."""
- _add_unique_id(msg)
- pack_context(msg, context)
- with ConnectionContext(conf, connection_pool, pooled=False,
- server_params=server_params) as conn:
- conn.topic_send(topic, rpc_common.serialize_msg(msg))
-
-
-def fanout_cast_to_server(conf, context, server_params, topic, msg,
- connection_pool):
- """Sends a message on a fanout exchange to a specific server."""
- _add_unique_id(msg)
- pack_context(msg, context)
- with ConnectionContext(conf, connection_pool, pooled=False,
- server_params=server_params) as conn:
- conn.fanout_send(topic, rpc_common.serialize_msg(msg))
-
-
-def notify(conf, context, topic, msg, connection_pool, envelope):
- """Sends a notification event on a topic."""
- LOG.debug(_('Sending %(event_type)s on %(topic)s'),
- dict(event_type=msg.get('event_type'),
- topic=topic))
- _add_unique_id(msg)
- pack_context(msg, context)
- with ConnectionContext(conf, connection_pool) as conn:
- if envelope:
- msg = rpc_common.serialize_msg(msg)
- conn.notify_send(topic, msg)
-
-
-def cleanup(connection_pool):
- if connection_pool:
- connection_pool.empty()
-
-
-def get_control_exchange(conf):
- return conf.control_exchange
diff --git a/openstack_dashboard/openstack/common/rpc/common.py b/openstack_dashboard/openstack/common/rpc/common.py
deleted file mode 100644
index f4a4ba81..00000000
--- a/openstack_dashboard/openstack/common/rpc/common.py
+++ /dev/null
@@ -1,516 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-# Copyright 2011 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import copy
-import sys
-import traceback
-
-from oslo.config import cfg
-import six
-
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import importutils
-from openstack_dashboard.openstack.common import jsonutils
-from openstack_dashboard.openstack.common import local
-from openstack_dashboard.openstack.common import log as logging
-
-
-CONF = cfg.CONF
-LOG = logging.getLogger(__name__)
-
-
-'''RPC Envelope Version.
-
-This version number applies to the top level structure of messages sent out.
-It does *not* apply to the message payload, which must be versioned
-independently. For example, when using rpc APIs, a version number is applied
-for changes to the API being exposed over rpc. This version number is handled
-in the rpc proxy and dispatcher modules.
-
-This version number applies to the message envelope that is used in the
-serialization done inside the rpc layer. See serialize_msg() and
-deserialize_msg().
-
-The current message format (version 2.0) is very simple. It is:
-
- {
- 'oslo.version': <RPC Envelope Version as a String>,
- 'oslo.message': <Application Message Payload, JSON encoded>
- }
-
-Message format version '1.0' is just considered to be the messages we sent
-without a message envelope.
-
-So, the current message envelope just includes the envelope version. It may
-eventually contain additional information, such as a signature for the message
-payload.
-
-We will JSON encode the application message payload. The message envelope,
-which includes the JSON encoded application message body, will be passed down
-to the messaging libraries as a dict.
-'''
-_RPC_ENVELOPE_VERSION = '2.0'
-
-_VERSION_KEY = 'oslo.version'
-_MESSAGE_KEY = 'oslo.message'
-
-
-class RPCException(Exception):
- message = _("An unknown RPC related exception occurred.")
-
- def __init__(self, message=None, **kwargs):
- self.kwargs = kwargs
-
- if not message:
- try:
- message = self.message % kwargs
-
- except Exception:
- # kwargs doesn't match a variable in the message
- # log the issue and the kwargs
- LOG.exception(_('Exception in string format operation'))
- for name, value in kwargs.iteritems():
- LOG.error("%s: %s" % (name, value))
- # at least get the core message out if something happened
- message = self.message
-
- super(RPCException, self).__init__(message)
-
-
-class RemoteError(RPCException):
- """Signifies that a remote class has raised an exception.
-
- Contains a string representation of the type of the original exception,
- the value of the original exception, and the traceback. These are
- sent to the parent as a joined string so printing the exception
- contains all of the relevant info.
-
- """
- message = _("Remote error: %(exc_type)s %(value)s\n%(traceback)s.")
-
- def __init__(self, exc_type=None, value=None, traceback=None):
- self.exc_type = exc_type
- self.value = value
- self.traceback = traceback
- super(RemoteError, self).__init__(exc_type=exc_type,
- value=value,
- traceback=traceback)
-
-
-class Timeout(RPCException):
- """Signifies that a timeout has occurred.
-
- This exception is raised if the rpc_response_timeout is reached while
- waiting for a response from the remote side.
- """
- message = _('Timeout while waiting on RPC response - '
- 'topic: "%(topic)s", RPC method: "%(method)s" '
- 'info: "%(info)s"')
-
- def __init__(self, info=None, topic=None, method=None):
- """
- :param info: Extra info to convey to the user
- :param topic: The topic that the rpc call was sent to
- :param rpc_method_name: The name of the rpc method being
- called
- """
- self.info = info
- self.topic = topic
- self.method = method
- super(Timeout, self).__init__(
- None,
- info=info or _('<unknown>'),
- topic=topic or _('<unknown>'),
- method=method or _('<unknown>'))
-
-
-class DuplicateMessageError(RPCException):
- message = _("Found duplicate message(%(msg_id)s). Skipping it.")
-
-
-class InvalidRPCConnectionReuse(RPCException):
- message = _("Invalid reuse of an RPC connection.")
-
-
-class UnsupportedRpcVersion(RPCException):
- message = _("Specified RPC version, %(version)s, not supported by "
- "this endpoint.")
-
-
-class UnsupportedRpcEnvelopeVersion(RPCException):
- message = _("Specified RPC envelope version, %(version)s, "
- "not supported by this endpoint.")
-
-
-class RpcVersionCapError(RPCException):
- message = _("Specified RPC version cap, %(version_cap)s, is too low")
-
-
-class Connection(object):
- """A connection, returned by rpc.create_connection().
-
- This class represents a connection to the message bus used for rpc.
- An instance of this class should never be created by users of the rpc API.
- Use rpc.create_connection() instead.
- """
- def close(self):
- """Close the connection.
-
- This method must be called when the connection will no longer be used.
- It will ensure that any resources associated with the connection, such
- as a network connection, and cleaned up.
- """
- raise NotImplementedError()
-
- def create_consumer(self, topic, proxy, fanout=False):
- """Create a consumer on this connection.
-
- A consumer is associated with a message queue on the backend message
- bus. The consumer will read messages from the queue, unpack them, and
- dispatch them to the proxy object. The contents of the message pulled
- off of the queue will determine which method gets called on the proxy
- object.
-
- :param topic: This is a name associated with what to consume from.
- Multiple instances of a service may consume from the same
- topic. For example, all instances of nova-compute consume
- from a queue called "compute". In that case, the
- messages will get distributed amongst the consumers in a
- round-robin fashion if fanout=False. If fanout=True,
- every consumer associated with this topic will get a
- copy of every message.
- :param proxy: The object that will handle all incoming messages.
- :param fanout: Whether or not this is a fanout topic. See the
- documentation for the topic parameter for some
- additional comments on this.
- """
- raise NotImplementedError()
-
- def create_worker(self, topic, proxy, pool_name):
- """Create a worker on this connection.
-
- A worker is like a regular consumer of messages directed to a
- topic, except that it is part of a set of such consumers (the
- "pool") which may run in parallel. Every pool of workers will
- receive a given message, but only one worker in the pool will
- be asked to process it. Load is distributed across the members
- of the pool in round-robin fashion.
-
- :param topic: This is a name associated with what to consume from.
- Multiple instances of a service may consume from the same
- topic.
- :param proxy: The object that will handle all incoming messages.
- :param pool_name: String containing the name of the pool of workers
- """
- raise NotImplementedError()
-
- def join_consumer_pool(self, callback, pool_name, topic, exchange_name):
- """Register as a member of a group of consumers for a given topic from
- the specified exchange.
-
- Exactly one member of a given pool will receive each message.
-
- A message will be delivered to multiple pools, if more than
- one is created.
-
- :param callback: Callable to be invoked for each message.
- :type callback: callable accepting one argument
- :param pool_name: The name of the consumer pool.
- :type pool_name: str
- :param topic: The routing topic for desired messages.
- :type topic: str
- :param exchange_name: The name of the message exchange where
- the client should attach. Defaults to
- the configured exchange.
- :type exchange_name: str
- """
- raise NotImplementedError()
-
- def consume_in_thread(self):
- """Spawn a thread to handle incoming messages.
-
- Spawn a thread that will be responsible for handling all incoming
- messages for consumers that were set up on this connection.
-
- Message dispatching inside of this is expected to be implemented in a
- non-blocking manner. An example implementation would be having this
- thread pull messages in for all of the consumers, but utilize a thread
- pool for dispatching the messages to the proxy objects.
- """
- raise NotImplementedError()
-
-
-def _safe_log(log_func, msg, msg_data):
- """Sanitizes the msg_data field before logging."""
- SANITIZE = {'set_admin_password': [('args', 'new_pass')],
- 'run_instance': [('args', 'admin_password')],
- 'route_message': [('args', 'message', 'args', 'method_info',
- 'method_kwargs', 'password'),
- ('args', 'message', 'args', 'method_info',
- 'method_kwargs', 'admin_password')]}
-
- has_method = 'method' in msg_data and msg_data['method'] in SANITIZE
- has_context_token = '_context_auth_token' in msg_data
- has_token = 'auth_token' in msg_data
-
- if not any([has_method, has_context_token, has_token]):
- return log_func(msg, msg_data)
-
- msg_data = copy.deepcopy(msg_data)
-
- if has_method:
- for arg in SANITIZE.get(msg_data['method'], []):
- try:
- d = msg_data
- for elem in arg[:-1]:
- d = d[elem]
- d[arg[-1]] = '<SANITIZED>'
- except KeyError as e:
- LOG.info(_('Failed to sanitize %(item)s. Key error %(err)s'),
- {'item': arg,
- 'err': e})
-
- if has_context_token:
- msg_data['_context_auth_token'] = '<SANITIZED>'
-
- if has_token:
- msg_data['auth_token'] = '<SANITIZED>'
-
- return log_func(msg, msg_data)
-
-
-def serialize_remote_exception(failure_info, log_failure=True):
- """Prepares exception data to be sent over rpc.
-
- Failure_info should be a sys.exc_info() tuple.
-
- """
- tb = traceback.format_exception(*failure_info)
- failure = failure_info[1]
- if log_failure:
- LOG.error(_("Returning exception %s to caller"),
- six.text_type(failure))
- LOG.error(tb)
-
- kwargs = {}
- if hasattr(failure, 'kwargs'):
- kwargs = failure.kwargs
-
- data = {
- 'class': str(failure.__class__.__name__),
- 'module': str(failure.__class__.__module__),
- 'message': six.text_type(failure),
- 'tb': tb,
- 'args': failure.args,
- 'kwargs': kwargs
- }
-
- json_data = jsonutils.dumps(data)
-
- return json_data
-
-
-def deserialize_remote_exception(conf, data):
- failure = jsonutils.loads(str(data))
-
- trace = failure.get('tb', [])
- message = failure.get('message', "") + "\n" + "\n".join(trace)
- name = failure.get('class')
- module = failure.get('module')
-
- # NOTE(ameade): We DO NOT want to allow just any module to be imported, in
- # order to prevent arbitrary code execution.
- if module not in conf.allowed_rpc_exception_modules:
- return RemoteError(name, failure.get('message'), trace)
-
- try:
- mod = importutils.import_module(module)
- klass = getattr(mod, name)
- if not issubclass(klass, Exception):
- raise TypeError("Can only deserialize Exceptions")
-
- failure = klass(*failure.get('args', []), **failure.get('kwargs', {}))
- except (AttributeError, TypeError, ImportError):
- return RemoteError(name, failure.get('message'), trace)
-
- ex_type = type(failure)
- str_override = lambda self: message
- new_ex_type = type(ex_type.__name__ + "_Remote", (ex_type,),
- {'__str__': str_override, '__unicode__': str_override})
- try:
- # NOTE(ameade): Dynamically create a new exception type and swap it in
- # as the new type for the exception. This only works on user defined
- # Exceptions and not core python exceptions. This is important because
- # we cannot necessarily change an exception message so we must override
- # the __str__ method.
- failure.__class__ = new_ex_type
- except TypeError:
- # NOTE(ameade): If a core exception then just add the traceback to the
- # first exception argument.
- failure.args = (message,) + failure.args[1:]
- return failure
-
-
-class CommonRpcContext(object):
- def __init__(self, **kwargs):
- self.values = kwargs
-
- def __getattr__(self, key):
- try:
- return self.values[key]
- except KeyError:
- raise AttributeError(key)
-
- def to_dict(self):
- return copy.deepcopy(self.values)
-
- @classmethod
- def from_dict(cls, values):
- return cls(**values)
-
- def deepcopy(self):
- return self.from_dict(self.to_dict())
-
- def update_store(self):
- local.store.context = self
-
- def elevated(self, read_deleted=None, overwrite=False):
- """Return a version of this context with admin flag set."""
- # TODO(russellb) This method is a bit of a nova-ism. It makes
- # some assumptions about the data in the request context sent
- # across rpc, while the rest of this class does not. We could get
- # rid of this if we changed the nova code that uses this to
- # convert the RpcContext back to its native RequestContext doing
- # something like nova.context.RequestContext.from_dict(ctxt.to_dict())
-
- context = self.deepcopy()
- context.values['is_admin'] = True
-
- context.values.setdefault('roles', [])
-
- if 'admin' not in context.values['roles']:
- context.values['roles'].append('admin')
-
- if read_deleted is not None:
- context.values['read_deleted'] = read_deleted
-
- return context
-
-
-class ClientException(Exception):
- """This encapsulates some actual exception that is expected to be
- hit by an RPC proxy object. Merely instantiating it records the
- current exception information, which will be passed back to the
- RPC client without exceptional logging.
- """
- def __init__(self):
- self._exc_info = sys.exc_info()
-
-
-def catch_client_exception(exceptions, func, *args, **kwargs):
- try:
- return func(*args, **kwargs)
- except Exception as e:
- if type(e) in exceptions:
- raise ClientException()
- else:
- raise
-
-
-def client_exceptions(*exceptions):
- """Decorator for manager methods that raise expected exceptions.
- Marking a Manager method with this decorator allows the declaration
- of expected exceptions that the RPC layer should not consider fatal,
- and not log as if they were generated in a real error scenario. Note
- that this will cause listed exceptions to be wrapped in a
- ClientException, which is used internally by the RPC layer.
- """
- def outer(func):
- def inner(*args, **kwargs):
- return catch_client_exception(exceptions, func, *args, **kwargs)
- return inner
- return outer
-
-
-def version_is_compatible(imp_version, version):
- """Determine whether versions are compatible.
-
- :param imp_version: The version implemented
- :param version: The version requested by an incoming message.
- """
- version_parts = version.split('.')
- imp_version_parts = imp_version.split('.')
- if int(version_parts[0]) != int(imp_version_parts[0]): # Major
- return False
- if int(version_parts[1]) > int(imp_version_parts[1]): # Minor
- return False
- return True
-
-
-def serialize_msg(raw_msg):
- # NOTE(russellb) See the docstring for _RPC_ENVELOPE_VERSION for more
- # information about this format.
- msg = {_VERSION_KEY: _RPC_ENVELOPE_VERSION,
- _MESSAGE_KEY: jsonutils.dumps(raw_msg)}
-
- return msg
-
-
-def deserialize_msg(msg):
- # NOTE(russellb): Hang on to your hats, this road is about to
- # get a little bumpy.
- #
- # Robustness Principle:
- # "Be strict in what you send, liberal in what you accept."
- #
- # At this point we have to do a bit of guessing about what it
- # is we just received. Here is the set of possibilities:
- #
- # 1) We received a dict. This could be 2 things:
- #
- # a) Inspect it to see if it looks like a standard message envelope.
- # If so, great!
- #
- # b) If it doesn't look like a standard message envelope, it could either
- # be a notification, or a message from before we added a message
- # envelope (referred to as version 1.0).
- # Just return the message as-is.
- #
- # 2) It's any other non-dict type. Just return it and hope for the best.
- # This case covers return values from rpc.call() from before message
- # envelopes were used. (messages to call a method were always a dict)
-
- if not isinstance(msg, dict):
- # See #2 above.
- return msg
-
- base_envelope_keys = (_VERSION_KEY, _MESSAGE_KEY)
- if not all(map(lambda key: key in msg, base_envelope_keys)):
- # See #1.b above.
- return msg
-
- # At this point we think we have the message envelope
- # format we were expecting. (#1.a above)
-
- if not version_is_compatible(_RPC_ENVELOPE_VERSION, msg[_VERSION_KEY]):
- raise UnsupportedRpcEnvelopeVersion(version=msg[_VERSION_KEY])
-
- raw_msg = jsonutils.loads(msg[_MESSAGE_KEY])
-
- return raw_msg
diff --git a/openstack_dashboard/openstack/common/rpc/dispatcher.py b/openstack_dashboard/openstack/common/rpc/dispatcher.py
deleted file mode 100644
index 1af52a1a..00000000
--- a/openstack_dashboard/openstack/common/rpc/dispatcher.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Code for rpc message dispatching.
-
-Messages that come in have a version number associated with them. RPC API
-version numbers are in the form:
-
- Major.Minor
-
-For a given message with version X.Y, the receiver must be marked as able to
-handle messages of version A.B, where:
-
- A = X
-
- B >= Y
-
-The Major version number would be incremented for an almost completely new API.
-The Minor version number would be incremented for backwards compatible changes
-to an existing API. A backwards compatible change could be something like
-adding a new method, adding an argument to an existing method (but not
-requiring it), or changing the type for an existing argument (but still
-handling the old type as well).
-
-The conversion over to a versioned API must be done on both the client side and
-server side of the API at the same time. However, as the code stands today,
-there can be both versioned and unversioned APIs implemented in the same code
-base.
-
-EXAMPLES
-========
-
-Nova was the first project to use versioned rpc APIs. Consider the compute rpc
-API as an example. The client side is in nova/compute/rpcapi.py and the server
-side is in nova/compute/manager.py.
-
-
-Example 1) Adding a new method.
--------------------------------
-
-Adding a new method is a backwards compatible change. It should be added to
-nova/compute/manager.py, and RPC_API_VERSION should be bumped from X.Y to
-X.Y+1. On the client side, the new method in nova/compute/rpcapi.py should
-have a specific version specified to indicate the minimum API version that must
-be implemented for the method to be supported. For example::
-
- def get_host_uptime(self, ctxt, host):
- topic = _compute_topic(self.topic, ctxt, host, None)
- return self.call(ctxt, self.make_msg('get_host_uptime'), topic,
- version='1.1')
-
-In this case, version '1.1' is the first version that supported the
-get_host_uptime() method.
-
-
-Example 2) Adding a new parameter.
-----------------------------------
-
-Adding a new parameter to an rpc method can be made backwards compatible. The
-RPC_API_VERSION on the server side (nova/compute/manager.py) should be bumped.
-The implementation of the method must not expect the parameter to be present.::
-
- def some_remote_method(self, arg1, arg2, newarg=None):
- # The code needs to deal with newarg=None for cases
- # where an older client sends a message without it.
- pass
-
-On the client side, the same changes should be made as in example 1. The
-minimum version that supports the new parameter should be specified.
-"""
-
-from openstack_dashboard.openstack.common.rpc import common as rpc_common
-from openstack_dashboard.openstack.common.rpc import serializer as rpc_serializer
-
-
-class RpcDispatcher(object):
- """Dispatch rpc messages according to the requested API version.
-
- This class can be used as the top level 'manager' for a service. It
- contains a list of underlying managers that have an API_VERSION attribute.
- """
-
- def __init__(self, callbacks, serializer=None):
- """Initialize the rpc dispatcher.
-
- :param callbacks: List of proxy objects that are an instance
- of a class with rpc methods exposed. Each proxy
- object should have an RPC_API_VERSION attribute.
- :param serializer: The Serializer object that will be used to
- deserialize arguments before the method call and
- to serialize the result after it returns.
- """
- self.callbacks = callbacks
- if serializer is None:
- serializer = rpc_serializer.NoOpSerializer()
- self.serializer = serializer
- super(RpcDispatcher, self).__init__()
-
- def _deserialize_args(self, context, kwargs):
- """Helper method called to deserialize args before dispatch.
-
- This calls our serializer on each argument, returning a new set of
- args that have been deserialized.
-
- :param context: The request context
- :param kwargs: The arguments to be deserialized
- :returns: A new set of deserialized args
- """
- new_kwargs = dict()
- for argname, arg in kwargs.iteritems():
- new_kwargs[argname] = self.serializer.deserialize_entity(context,
- arg)
- return new_kwargs
-
- def dispatch(self, ctxt, version, method, namespace, **kwargs):
- """Dispatch a message based on a requested version.
-
- :param ctxt: The request context
- :param version: The requested API version from the incoming message
- :param method: The method requested to be called by the incoming
- message.
- :param namespace: The namespace for the requested method. If None,
- the dispatcher will look for a method on a callback
- object with no namespace set.
- :param kwargs: A dict of keyword arguments to be passed to the method.
-
- :returns: Whatever is returned by the underlying method that gets
- called.
- """
- if not version:
- version = '1.0'
-
- had_compatible = False
- for proxyobj in self.callbacks:
- # Check for namespace compatibility
- try:
- cb_namespace = proxyobj.RPC_API_NAMESPACE
- except AttributeError:
- cb_namespace = None
-
- if namespace != cb_namespace:
- continue
-
- # Check for version compatibility
- try:
- rpc_api_version = proxyobj.RPC_API_VERSION
- except AttributeError:
- rpc_api_version = '1.0'
-
- is_compatible = rpc_common.version_is_compatible(rpc_api_version,
- version)
- had_compatible = had_compatible or is_compatible
-
- if not hasattr(proxyobj, method):
- continue
- if is_compatible:
- kwargs = self._deserialize_args(ctxt, kwargs)
- result = getattr(proxyobj, method)(ctxt, **kwargs)
- return self.serializer.serialize_entity(ctxt, result)
-
- if had_compatible:
- raise AttributeError("No such RPC function '%s'" % method)
- else:
- raise rpc_common.UnsupportedRpcVersion(version=version)
diff --git a/openstack_dashboard/openstack/common/rpc/impl_fake.py b/openstack_dashboard/openstack/common/rpc/impl_fake.py
deleted file mode 100644
index 3467986b..00000000
--- a/openstack_dashboard/openstack/common/rpc/impl_fake.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 OpenStack Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-"""Fake RPC implementation which calls proxy methods directly with no
-queues. Casts will block, but this is very useful for tests.
-"""
-
-import inspect
-# NOTE(russellb): We specifically want to use json, not our own jsonutils.
-# jsonutils has some extra logic to automatically convert objects to primitive
-# types so that they can be serialized. We want to catch all cases where
-# non-primitive types make it into this code and treat it as an error.
-import json
-import time
-
-import eventlet
-
-from openstack_dashboard.openstack.common.rpc import common as rpc_common
-
-CONSUMERS = {}
-
-
-class RpcContext(rpc_common.CommonRpcContext):
- def __init__(self, **kwargs):
- super(RpcContext, self).__init__(**kwargs)
- self._response = []
- self._done = False
-
- def deepcopy(self):
- values = self.to_dict()
- new_inst = self.__class__(**values)
- new_inst._response = self._response
- new_inst._done = self._done
- return new_inst
-
- def reply(self, reply=None, failure=None, ending=False):
- if ending:
- self._done = True
- if not self._done:
- self._response.append((reply, failure))
-
-
-class Consumer(object):
- def __init__(self, topic, proxy):
- self.topic = topic
- self.proxy = proxy
-
- def call(self, context, version, method, namespace, args, timeout):
- done = eventlet.event.Event()
-
- def _inner():
- ctxt = RpcContext.from_dict(context.to_dict())
- try:
- rval = self.proxy.dispatch(context, version, method,
- namespace, **args)
- res = []
- # Caller might have called ctxt.reply() manually
- for (reply, failure) in ctxt._response:
- if failure:
- raise failure[0], failure[1], failure[2]
- res.append(reply)
- # if ending not 'sent'...we might have more data to
- # return from the function itself
- if not ctxt._done:
- if inspect.isgenerator(rval):
- for val in rval:
- res.append(val)
- else:
- res.append(rval)
- done.send(res)
- except rpc_common.ClientException as e:
- done.send_exception(e._exc_info[1])
- except Exception as e:
- done.send_exception(e)
-
- thread = eventlet.greenthread.spawn(_inner)
-
- if timeout:
- start_time = time.time()
- while not done.ready():
- eventlet.greenthread.sleep(1)
- cur_time = time.time()
- if (cur_time - start_time) > timeout:
- thread.kill()
- raise rpc_common.Timeout()
-
- return done.wait()
-
-
-class Connection(object):
- """Connection object."""
-
- def __init__(self):
- self.consumers = []
-
- def create_consumer(self, topic, proxy, fanout=False):
- consumer = Consumer(topic, proxy)
- self.consumers.append(consumer)
- if topic not in CONSUMERS:
- CONSUMERS[topic] = []
- CONSUMERS[topic].append(consumer)
-
- def close(self):
- for consumer in self.consumers:
- CONSUMERS[consumer.topic].remove(consumer)
- self.consumers = []
-
- def consume_in_thread(self):
- pass
-
-
-def create_connection(conf, new=True):
- """Create a connection."""
- return Connection()
-
-
-def check_serialize(msg):
- """Make sure a message intended for rpc can be serialized."""
- json.dumps(msg)
-
-
-def multicall(conf, context, topic, msg, timeout=None):
- """Make a call that returns multiple times."""
-
- check_serialize(msg)
-
- method = msg.get('method')
- if not method:
- return
- args = msg.get('args', {})
- version = msg.get('version', None)
- namespace = msg.get('namespace', None)
-
- try:
- consumer = CONSUMERS[topic][0]
- except (KeyError, IndexError):
- return iter([None])
- else:
- return consumer.call(context, version, method, namespace, args,
- timeout)
-
-
-def call(conf, context, topic, msg, timeout=None):
- """Sends a message on a topic and wait for a response."""
- rv = multicall(conf, context, topic, msg, timeout)
- # NOTE(vish): return the last result from the multicall
- rv = list(rv)
- if not rv:
- return
- return rv[-1]
-
-
-def cast(conf, context, topic, msg):
- check_serialize(msg)
- try:
- call(conf, context, topic, msg)
- except Exception:
- pass
-
-
-def notify(conf, context, topic, msg, envelope):
- check_serialize(msg)
-
-
-def cleanup():
- pass
-
-
-def fanout_cast(conf, context, topic, msg):
- """Cast to all consumers of a topic."""
- check_serialize(msg)
- method = msg.get('method')
- if not method:
- return
- args = msg.get('args', {})
- version = msg.get('version', None)
- namespace = msg.get('namespace', None)
-
- for consumer in CONSUMERS.get(topic, []):
- try:
- consumer.call(context, version, method, namespace, args, None)
- except Exception:
- pass
diff --git a/openstack_dashboard/openstack/common/rpc/impl_kombu.py b/openstack_dashboard/openstack/common/rpc/impl_kombu.py
deleted file mode 100644
index 8f885b2d..00000000
--- a/openstack_dashboard/openstack/common/rpc/impl_kombu.py
+++ /dev/null
@@ -1,839 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 OpenStack Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import functools
-import itertools
-import socket
-import ssl
-import sys
-import time
-import uuid
-
-import eventlet
-import greenlet
-import kombu
-import kombu.connection
-import kombu.entity
-import kombu.messaging
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import network_utils
-from openstack_dashboard.openstack.common.rpc import amqp as rpc_amqp
-from openstack_dashboard.openstack.common.rpc import common as rpc_common
-
-kombu_opts = [
- cfg.StrOpt('kombu_ssl_version',
- default='',
- help='SSL version to use (valid only if SSL enabled)'),
- cfg.StrOpt('kombu_ssl_keyfile',
- default='',
- help='SSL key file (valid only if SSL enabled)'),
- cfg.StrOpt('kombu_ssl_certfile',
- default='',
- help='SSL cert file (valid only if SSL enabled)'),
- cfg.StrOpt('kombu_ssl_ca_certs',
- default='',
- help=('SSL certification authority file '
- '(valid only if SSL enabled)')),
- cfg.StrOpt('rabbit_host',
- default='localhost',
- help='The RabbitMQ broker address where a single node is used'),
- cfg.IntOpt('rabbit_port',
- default=5672,
- help='The RabbitMQ broker port where a single node is used'),
- cfg.ListOpt('rabbit_hosts',
- default=['$rabbit_host:$rabbit_port'],
- help='RabbitMQ HA cluster host:port pairs'),
- cfg.BoolOpt('rabbit_use_ssl',
- default=False,
- help='connect over SSL for RabbitMQ'),
- cfg.StrOpt('rabbit_userid',
- default='guest',
- help='the RabbitMQ userid'),
- cfg.StrOpt('rabbit_password',
- default='guest',
- help='the RabbitMQ password',
- secret=True),
- cfg.StrOpt('rabbit_virtual_host',
- default='/',
- help='the RabbitMQ virtual host'),
- cfg.IntOpt('rabbit_retry_interval',
- default=1,
- help='how frequently to retry connecting with RabbitMQ'),
- cfg.IntOpt('rabbit_retry_backoff',
- default=2,
- help='how long to backoff for between retries when connecting '
- 'to RabbitMQ'),
- cfg.IntOpt('rabbit_max_retries',
- default=0,
- help='maximum retries with trying to connect to RabbitMQ '
- '(the default of 0 implies an infinite retry count)'),
- cfg.BoolOpt('rabbit_durable_queues',
- default=False,
- help='use durable queues in RabbitMQ'),
- cfg.BoolOpt('rabbit_ha_queues',
- default=False,
- help='use H/A queues in RabbitMQ (x-ha-policy: all).'
- 'You need to wipe RabbitMQ database when '
- 'changing this option.'),
-
-]
-
-cfg.CONF.register_opts(kombu_opts)
-
-LOG = rpc_common.LOG
-
-
-def _get_queue_arguments(conf):
- """Construct the arguments for declaring a queue.
-
- If the rabbit_ha_queues option is set, we declare a mirrored queue
- as described here:
-
- http://www.rabbitmq.com/ha.html
-
- Setting x-ha-policy to all means that the queue will be mirrored
- to all nodes in the cluster.
- """
- return {'x-ha-policy': 'all'} if conf.rabbit_ha_queues else {}
-
-
-class ConsumerBase(object):
- """Consumer base class."""
-
- def __init__(self, channel, callback, tag, **kwargs):
- """Declare a queue on an amqp channel.
-
- 'channel' is the amqp channel to use
- 'callback' is the callback to call when messages are received
- 'tag' is a unique ID for the consumer on the channel
-
- queue name, exchange name, and other kombu options are
- passed in here as a dictionary.
- """
- self.callback = callback
- self.tag = str(tag)
- self.kwargs = kwargs
- self.queue = None
- self.reconnect(channel)
-
- def reconnect(self, channel):
- """Re-declare the queue after a rabbit reconnect."""
- self.channel = channel
- self.kwargs['channel'] = channel
- self.queue = kombu.entity.Queue(**self.kwargs)
- self.queue.declare()
-
- def consume(self, *args, **kwargs):
- """Actually declare the consumer on the amqp channel. This will
- start the flow of messages from the queue. Using the
- Connection.iterconsume() iterator will process the messages,
- calling the appropriate callback.
-
- If a callback is specified in kwargs, use that. Otherwise,
- use the callback passed during __init__()
-
- If kwargs['nowait'] is True, then this call will block until
- a message is read.
-
- Messages will automatically be acked if the callback doesn't
- raise an exception
- """
-
- options = {'consumer_tag': self.tag}
- options['nowait'] = kwargs.get('nowait', False)
- callback = kwargs.get('callback', self.callback)
- if not callback:
- raise ValueError("No callback defined")
-
- def _callback(raw_message):
- message = self.channel.message_to_python(raw_message)
- try:
- msg = rpc_common.deserialize_msg(message.payload)
- callback(msg)
- except Exception:
- LOG.exception(_("Failed to process message... skipping it."))
- finally:
- message.ack()
-
- self.queue.consume(*args, callback=_callback, **options)
-
- def cancel(self):
- """Cancel the consuming from the queue, if it has started."""
- try:
- self.queue.cancel(self.tag)
- except KeyError as e:
- # NOTE(comstud): Kludge to get around a amqplib bug
- if str(e) != "u'%s'" % self.tag:
- raise
- self.queue = None
-
-
-class DirectConsumer(ConsumerBase):
- """Queue/consumer class for 'direct'."""
-
- def __init__(self, conf, channel, msg_id, callback, tag, **kwargs):
- """Init a 'direct' queue.
-
- 'channel' is the amqp channel to use
- 'msg_id' is the msg_id to listen on
- 'callback' is the callback to call when messages are received
- 'tag' is a unique ID for the consumer on the channel
-
- Other kombu options may be passed
- """
- # Default options
- options = {'durable': False,
- 'queue_arguments': _get_queue_arguments(conf),
- 'auto_delete': True,
- 'exclusive': False}
- options.update(kwargs)
- exchange = kombu.entity.Exchange(name=msg_id,
- type='direct',
- durable=options['durable'],
- auto_delete=options['auto_delete'])
- super(DirectConsumer, self).__init__(channel,
- callback,
- tag,
- name=msg_id,
- exchange=exchange,
- routing_key=msg_id,
- **options)
-
-
-class TopicConsumer(ConsumerBase):
- """Consumer class for 'topic'."""
-
- def __init__(self, conf, channel, topic, callback, tag, name=None,
- exchange_name=None, **kwargs):
- """Init a 'topic' queue.
-
- :param channel: the amqp channel to use
- :param topic: the topic to listen on
- :paramtype topic: str
- :param callback: the callback to call when messages are received
- :param tag: a unique ID for the consumer on the channel
- :param name: optional queue name, defaults to topic
- :paramtype name: str
-
- Other kombu options may be passed as keyword arguments
- """
- # Default options
- options = {'durable': conf.rabbit_durable_queues,
- 'queue_arguments': _get_queue_arguments(conf),
- 'auto_delete': False,
- 'exclusive': False}
- options.update(kwargs)
- exchange_name = exchange_name or rpc_amqp.get_control_exchange(conf)
- exchange = kombu.entity.Exchange(name=exchange_name,
- type='topic',
- durable=options['durable'],
- auto_delete=options['auto_delete'])
- super(TopicConsumer, self).__init__(channel,
- callback,
- tag,
- name=name or topic,
- exchange=exchange,
- routing_key=topic,
- **options)
-
-
-class FanoutConsumer(ConsumerBase):
- """Consumer class for 'fanout'."""
-
- def __init__(self, conf, channel, topic, callback, tag, **kwargs):
- """Init a 'fanout' queue.
-
- 'channel' is the amqp channel to use
- 'topic' is the topic to listen on
- 'callback' is the callback to call when messages are received
- 'tag' is a unique ID for the consumer on the channel
-
- Other kombu options may be passed
- """
- unique = uuid.uuid4().hex
- exchange_name = '%s_fanout' % topic
- queue_name = '%s_fanout_%s' % (topic, unique)
-
- # Default options
- options = {'durable': False,
- 'queue_arguments': _get_queue_arguments(conf),
- 'auto_delete': True,
- 'exclusive': False}
- options.update(kwargs)
- exchange = kombu.entity.Exchange(name=exchange_name, type='fanout',
- durable=options['durable'],
- auto_delete=options['auto_delete'])
- super(FanoutConsumer, self).__init__(channel, callback, tag,
- name=queue_name,
- exchange=exchange,
- routing_key=topic,
- **options)
-
-
-class Publisher(object):
- """Base Publisher class."""
-
- def __init__(self, channel, exchange_name, routing_key, **kwargs):
- """Init the Publisher class with the exchange_name, routing_key,
- and other options
- """
- self.exchange_name = exchange_name
- self.routing_key = routing_key
- self.kwargs = kwargs
- self.reconnect(channel)
-
- def reconnect(self, channel):
- """Re-establish the Producer after a rabbit reconnection."""
- self.exchange = kombu.entity.Exchange(name=self.exchange_name,
- **self.kwargs)
- self.producer = kombu.messaging.Producer(exchange=self.exchange,
- channel=channel,
- routing_key=self.routing_key)
-
- def send(self, msg, timeout=None):
- """Send a message."""
- if timeout:
- #
- # AMQP TTL is in milliseconds when set in the header.
- #
- self.producer.publish(msg, headers={'ttl': (timeout * 1000)})
- else:
- self.producer.publish(msg)
-
-
-class DirectPublisher(Publisher):
- """Publisher class for 'direct'."""
- def __init__(self, conf, channel, msg_id, **kwargs):
- """init a 'direct' publisher.
-
- Kombu options may be passed as keyword args to override defaults
- """
-
- options = {'durable': False,
- 'auto_delete': True,
- 'exclusive': False}
- options.update(kwargs)
- super(DirectPublisher, self).__init__(channel, msg_id, msg_id,
- type='direct', **options)
-
-
-class TopicPublisher(Publisher):
- """Publisher class for 'topic'."""
- def __init__(self, conf, channel, topic, **kwargs):
- """init a 'topic' publisher.
-
- Kombu options may be passed as keyword args to override defaults
- """
- options = {'durable': conf.rabbit_durable_queues,
- 'auto_delete': False,
- 'exclusive': False}
- options.update(kwargs)
- exchange_name = rpc_amqp.get_control_exchange(conf)
- super(TopicPublisher, self).__init__(channel,
- exchange_name,
- topic,
- type='topic',
- **options)
-
-
-class FanoutPublisher(Publisher):
- """Publisher class for 'fanout'."""
- def __init__(self, conf, channel, topic, **kwargs):
- """init a 'fanout' publisher.
-
- Kombu options may be passed as keyword args to override defaults
- """
- options = {'durable': False,
- 'auto_delete': True,
- 'exclusive': False}
- options.update(kwargs)
- super(FanoutPublisher, self).__init__(channel, '%s_fanout' % topic,
- None, type='fanout', **options)
-
-
-class NotifyPublisher(TopicPublisher):
- """Publisher class for 'notify'."""
-
- def __init__(self, conf, channel, topic, **kwargs):
- self.durable = kwargs.pop('durable', conf.rabbit_durable_queues)
- self.queue_arguments = _get_queue_arguments(conf)
- super(NotifyPublisher, self).__init__(conf, channel, topic, **kwargs)
-
- def reconnect(self, channel):
- super(NotifyPublisher, self).reconnect(channel)
-
- # NOTE(jerdfelt): Normally the consumer would create the queue, but
- # we do this to ensure that messages don't get dropped if the
- # consumer is started after we do
- queue = kombu.entity.Queue(channel=channel,
- exchange=self.exchange,
- durable=self.durable,
- name=self.routing_key,
- routing_key=self.routing_key,
- queue_arguments=self.queue_arguments)
- queue.declare()
-
-
-class Connection(object):
- """Connection object."""
-
- pool = None
-
- def __init__(self, conf, server_params=None):
- self.consumers = []
- self.consumer_thread = None
- self.proxy_callbacks = []
- self.conf = conf
- self.max_retries = self.conf.rabbit_max_retries
- # Try forever?
- if self.max_retries <= 0:
- self.max_retries = None
- self.interval_start = self.conf.rabbit_retry_interval
- self.interval_stepping = self.conf.rabbit_retry_backoff
- # max retry-interval = 30 seconds
- self.interval_max = 30
- self.memory_transport = False
-
- if server_params is None:
- server_params = {}
- # Keys to translate from server_params to kombu params
- server_params_to_kombu_params = {'username': 'userid'}
-
- ssl_params = self._fetch_ssl_params()
- params_list = []
- for adr in self.conf.rabbit_hosts:
- hostname, port = network_utils.parse_host_port(
- adr, default_port=self.conf.rabbit_port)
-
- params = {
- 'hostname': hostname,
- 'port': port,
- 'userid': self.conf.rabbit_userid,
- 'password': self.conf.rabbit_password,
- 'virtual_host': self.conf.rabbit_virtual_host,
- }
-
- for sp_key, value in server_params.iteritems():
- p_key = server_params_to_kombu_params.get(sp_key, sp_key)
- params[p_key] = value
-
- if self.conf.fake_rabbit:
- params['transport'] = 'memory'
- if self.conf.rabbit_use_ssl:
- params['ssl'] = ssl_params
-
- params_list.append(params)
-
- self.params_list = params_list
-
- self.memory_transport = self.conf.fake_rabbit
-
- self.connection = None
- self.reconnect()
-
- def _fetch_ssl_params(self):
- """Handles fetching what ssl params should be used for the connection
- (if any).
- """
- ssl_params = dict()
-
- # http://docs.python.org/library/ssl.html - ssl.wrap_socket
- if self.conf.kombu_ssl_version:
- ssl_params['ssl_version'] = self.conf.kombu_ssl_version
- if self.conf.kombu_ssl_keyfile:
- ssl_params['keyfile'] = self.conf.kombu_ssl_keyfile
- if self.conf.kombu_ssl_certfile:
- ssl_params['certfile'] = self.conf.kombu_ssl_certfile
- if self.conf.kombu_ssl_ca_certs:
- ssl_params['ca_certs'] = self.conf.kombu_ssl_ca_certs
- # We might want to allow variations in the
- # future with this?
- ssl_params['cert_reqs'] = ssl.CERT_REQUIRED
-
- if not ssl_params:
- # Just have the default behavior
- return True
- else:
- # Return the extended behavior
- return ssl_params
-
- def _connect(self, params):
- """Connect to rabbit. Re-establish any queues that may have
- been declared before if we are reconnecting. Exceptions should
- be handled by the caller.
- """
- if self.connection:
- LOG.info(_("Reconnecting to AMQP server on "
- "%(hostname)s:%(port)d") % params)
- try:
- self.connection.release()
- except self.connection_errors:
- pass
- # Setting this in case the next statement fails, though
- # it shouldn't be doing any network operations, yet.
- self.connection = None
- self.connection = kombu.connection.BrokerConnection(**params)
- self.connection_errors = self.connection.connection_errors
- if self.memory_transport:
- # Kludge to speed up tests.
- self.connection.transport.polling_interval = 0.0
- self.consumer_num = itertools.count(1)
- self.connection.connect()
- self.channel = self.connection.channel()
- # work around 'memory' transport bug in 1.1.3
- if self.memory_transport:
- self.channel._new_queue('ae.undeliver')
- for consumer in self.consumers:
- consumer.reconnect(self.channel)
- LOG.info(_('Connected to AMQP server on %(hostname)s:%(port)d') %
- params)
-
- def reconnect(self):
- """Handles reconnecting and re-establishing queues.
- Will retry up to self.max_retries number of times.
- self.max_retries = 0 means to retry forever.
- Sleep between tries, starting at self.interval_start
- seconds, backing off self.interval_stepping number of seconds
- each attempt.
- """
-
- attempt = 0
- while True:
- params = self.params_list[attempt % len(self.params_list)]
- attempt += 1
- try:
- self._connect(params)
- return
- except (IOError, self.connection_errors) as e:
- pass
- except Exception as e:
- # NOTE(comstud): Unfortunately it's possible for amqplib
- # to return an error not covered by its transport
- # connection_errors in the case of a timeout waiting for
- # a protocol response. (See paste link in LP888621)
- # So, we check all exceptions for 'timeout' in them
- # and try to reconnect in this case.
- if 'timeout' not in str(e):
- raise
-
- log_info = {}
- log_info['err_str'] = str(e)
- log_info['max_retries'] = self.max_retries
- log_info.update(params)
-
- if self.max_retries and attempt == self.max_retries:
- LOG.error(_('Unable to connect to AMQP server on '
- '%(hostname)s:%(port)d after %(max_retries)d '
- 'tries: %(err_str)s') % log_info)
- # NOTE(comstud): Copied from original code. There's
- # really no better recourse because if this was a queue we
- # need to consume on, we have no way to consume anymore.
- sys.exit(1)
-
- if attempt == 1:
- sleep_time = self.interval_start or 1
- elif attempt > 1:
- sleep_time += self.interval_stepping
- if self.interval_max:
- sleep_time = min(sleep_time, self.interval_max)
-
- log_info['sleep_time'] = sleep_time
- LOG.error(_('AMQP server on %(hostname)s:%(port)d is '
- 'unreachable: %(err_str)s. Trying again in '
- '%(sleep_time)d seconds.') % log_info)
- time.sleep(sleep_time)
-
- def ensure(self, error_callback, method, *args, **kwargs):
- while True:
- try:
- return method(*args, **kwargs)
- except (self.connection_errors, socket.timeout, IOError) as e:
- if error_callback:
- error_callback(e)
- except Exception as e:
- # NOTE(comstud): Unfortunately it's possible for amqplib
- # to return an error not covered by its transport
- # connection_errors in the case of a timeout waiting for
- # a protocol response. (See paste link in LP888621)
- # So, we check all exceptions for 'timeout' in them
- # and try to reconnect in this case.
- if 'timeout' not in str(e):
- raise
- if error_callback:
- error_callback(e)
- self.reconnect()
-
- def get_channel(self):
- """Convenience call for bin/clear_rabbit_queues."""
- return self.channel
-
- def close(self):
- """Close/release this connection."""
- self.cancel_consumer_thread()
- self.wait_on_proxy_callbacks()
- self.connection.release()
- self.connection = None
-
- def reset(self):
- """Reset a connection so it can be used again."""
- self.cancel_consumer_thread()
- self.wait_on_proxy_callbacks()
- self.channel.close()
- self.channel = self.connection.channel()
- # work around 'memory' transport bug in 1.1.3
- if self.memory_transport:
- self.channel._new_queue('ae.undeliver')
- self.consumers = []
-
- def declare_consumer(self, consumer_cls, topic, callback):
- """Create a Consumer using the class that was passed in and
- add it to our list of consumers
- """
-
- def _connect_error(exc):
- log_info = {'topic': topic, 'err_str': str(exc)}
- LOG.error(_("Failed to declare consumer for topic '%(topic)s': "
- "%(err_str)s") % log_info)
-
- def _declare_consumer():
- consumer = consumer_cls(self.conf, self.channel, topic, callback,
- self.consumer_num.next())
- self.consumers.append(consumer)
- return consumer
-
- return self.ensure(_connect_error, _declare_consumer)
-
- def iterconsume(self, limit=None, timeout=None):
- """Return an iterator that will consume from all queues/consumers."""
-
- info = {'do_consume': True}
-
- def _error_callback(exc):
- if isinstance(exc, socket.timeout):
- LOG.debug(_('Timed out waiting for RPC response: %s') %
- str(exc))
- raise rpc_common.Timeout()
- else:
- LOG.exception(_('Failed to consume message from queue: %s') %
- str(exc))
- info['do_consume'] = True
-
- def _consume():
- if info['do_consume']:
- queues_head = self.consumers[:-1]
- queues_tail = self.consumers[-1]
- for queue in queues_head:
- queue.consume(nowait=True)
- queues_tail.consume(nowait=False)
- info['do_consume'] = False
- return self.connection.drain_events(timeout=timeout)
-
- for iteration in itertools.count(0):
- if limit and iteration >= limit:
- raise StopIteration
- yield self.ensure(_error_callback, _consume)
-
- def cancel_consumer_thread(self):
- """Cancel a consumer thread."""
- if self.consumer_thread is not None:
- self.consumer_thread.kill()
- try:
- self.consumer_thread.wait()
- except greenlet.GreenletExit:
- pass
- self.consumer_thread = None
-
- def wait_on_proxy_callbacks(self):
- """Wait for all proxy callback threads to exit."""
- for proxy_cb in self.proxy_callbacks:
- proxy_cb.wait()
-
- def publisher_send(self, cls, topic, msg, timeout=None, **kwargs):
- """Send to a publisher based on the publisher class."""
-
- def _error_callback(exc):
- log_info = {'topic': topic, 'err_str': str(exc)}
- LOG.exception(_("Failed to publish message to topic "
- "'%(topic)s': %(err_str)s") % log_info)
-
- def _publish():
- publisher = cls(self.conf, self.channel, topic, **kwargs)
- publisher.send(msg, timeout)
-
- self.ensure(_error_callback, _publish)
-
- def declare_direct_consumer(self, topic, callback):
- """Create a 'direct' queue.
- In nova's use, this is generally a msg_id queue used for
- responses for call/multicall
- """
- self.declare_consumer(DirectConsumer, topic, callback)
-
- def declare_topic_consumer(self, topic, callback=None, queue_name=None,
- exchange_name=None):
- """Create a 'topic' consumer."""
- self.declare_consumer(functools.partial(TopicConsumer,
- name=queue_name,
- exchange_name=exchange_name,
- ),
- topic, callback)
-
- def declare_fanout_consumer(self, topic, callback):
- """Create a 'fanout' consumer."""
- self.declare_consumer(FanoutConsumer, topic, callback)
-
- def direct_send(self, msg_id, msg):
- """Send a 'direct' message."""
- self.publisher_send(DirectPublisher, msg_id, msg)
-
- def topic_send(self, topic, msg, timeout=None):
- """Send a 'topic' message."""
- self.publisher_send(TopicPublisher, topic, msg, timeout)
-
- def fanout_send(self, topic, msg):
- """Send a 'fanout' message."""
- self.publisher_send(FanoutPublisher, topic, msg)
-
- def notify_send(self, topic, msg, **kwargs):
- """Send a notify message on a topic."""
- self.publisher_send(NotifyPublisher, topic, msg, None, **kwargs)
-
- def consume(self, limit=None):
- """Consume from all queues/consumers."""
- it = self.iterconsume(limit=limit)
- while True:
- try:
- it.next()
- except StopIteration:
- return
-
- def consume_in_thread(self):
- """Consumer from all queues/consumers in a greenthread."""
- def _consumer_thread():
- try:
- self.consume()
- except greenlet.GreenletExit:
- return
- if self.consumer_thread is None:
- self.consumer_thread = eventlet.spawn(_consumer_thread)
- return self.consumer_thread
-
- def create_consumer(self, topic, proxy, fanout=False):
- """Create a consumer that calls a method in a proxy object."""
- proxy_cb = rpc_amqp.ProxyCallback(
- self.conf, proxy,
- rpc_amqp.get_connection_pool(self.conf, Connection))
- self.proxy_callbacks.append(proxy_cb)
-
- if fanout:
- self.declare_fanout_consumer(topic, proxy_cb)
- else:
- self.declare_topic_consumer(topic, proxy_cb)
-
- def create_worker(self, topic, proxy, pool_name):
- """Create a worker that calls a method in a proxy object."""
- proxy_cb = rpc_amqp.ProxyCallback(
- self.conf, proxy,
- rpc_amqp.get_connection_pool(self.conf, Connection))
- self.proxy_callbacks.append(proxy_cb)
- self.declare_topic_consumer(topic, proxy_cb, pool_name)
-
- def join_consumer_pool(self, callback, pool_name, topic,
- exchange_name=None):
- """Register as a member of a group of consumers for a given topic from
- the specified exchange.
-
- Exactly one member of a given pool will receive each message.
-
- A message will be delivered to multiple pools, if more than
- one is created.
- """
- callback_wrapper = rpc_amqp.CallbackWrapper(
- conf=self.conf,
- callback=callback,
- connection_pool=rpc_amqp.get_connection_pool(self.conf,
- Connection),
- )
- self.proxy_callbacks.append(callback_wrapper)
- self.declare_topic_consumer(
- queue_name=pool_name,
- topic=topic,
- exchange_name=exchange_name,
- callback=callback_wrapper,
- )
-
-
-def create_connection(conf, new=True):
- """Create a connection."""
- return rpc_amqp.create_connection(
- conf, new,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def multicall(conf, context, topic, msg, timeout=None):
- """Make a call that returns multiple times."""
- return rpc_amqp.multicall(
- conf, context, topic, msg, timeout,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def call(conf, context, topic, msg, timeout=None):
- """Sends a message on a topic and wait for a response."""
- return rpc_amqp.call(
- conf, context, topic, msg, timeout,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def cast(conf, context, topic, msg):
- """Sends a message on a topic without waiting for a response."""
- return rpc_amqp.cast(
- conf, context, topic, msg,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def fanout_cast(conf, context, topic, msg):
- """Sends a message on a fanout exchange without waiting for a response."""
- return rpc_amqp.fanout_cast(
- conf, context, topic, msg,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def cast_to_server(conf, context, server_params, topic, msg):
- """Sends a message on a topic to a specific server."""
- return rpc_amqp.cast_to_server(
- conf, context, server_params, topic, msg,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def fanout_cast_to_server(conf, context, server_params, topic, msg):
- """Sends a message on a fanout exchange to a specific server."""
- return rpc_amqp.fanout_cast_to_server(
- conf, context, server_params, topic, msg,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def notify(conf, context, topic, msg, envelope):
- """Sends a notification event on a topic."""
- return rpc_amqp.notify(
- conf, context, topic, msg,
- rpc_amqp.get_connection_pool(conf, Connection),
- envelope)
-
-
-def cleanup():
- return rpc_amqp.cleanup(Connection.pool)
diff --git a/openstack_dashboard/openstack/common/rpc/impl_qpid.py b/openstack_dashboard/openstack/common/rpc/impl_qpid.py
deleted file mode 100644
index ce1fb129..00000000
--- a/openstack_dashboard/openstack/common/rpc/impl_qpid.py
+++ /dev/null
@@ -1,703 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 OpenStack Foundation
-# Copyright 2011 - 2012, Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import functools
-import itertools
-import time
-import uuid
-
-import eventlet
-import greenlet
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import importutils
-from openstack_dashboard.openstack.common import jsonutils
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common.rpc import amqp as rpc_amqp
-from openstack_dashboard.openstack.common.rpc import common as rpc_common
-
-qpid_codec = importutils.try_import("qpid.codec010")
-qpid_messaging = importutils.try_import("qpid.messaging")
-qpid_exceptions = importutils.try_import("qpid.messaging.exceptions")
-
-LOG = logging.getLogger(__name__)
-
-qpid_opts = [
- cfg.StrOpt('qpid_hostname',
- default='localhost',
- help='Qpid broker hostname'),
- cfg.IntOpt('qpid_port',
- default=5672,
- help='Qpid broker port'),
- cfg.ListOpt('qpid_hosts',
- default=['$qpid_hostname:$qpid_port'],
- help='Qpid HA cluster host:port pairs'),
- cfg.StrOpt('qpid_username',
- default='',
- help='Username for qpid connection'),
- cfg.StrOpt('qpid_password',
- default='',
- help='Password for qpid connection',
- secret=True),
- cfg.StrOpt('qpid_sasl_mechanisms',
- default='',
- help='Space separated list of SASL mechanisms to use for auth'),
- cfg.IntOpt('qpid_heartbeat',
- default=60,
- help='Seconds between connection keepalive heartbeats'),
- cfg.StrOpt('qpid_protocol',
- default='tcp',
- help="Transport to use, either 'tcp' or 'ssl'"),
- cfg.BoolOpt('qpid_tcp_nodelay',
- default=True,
- help='Disable Nagle algorithm'),
-]
-
-cfg.CONF.register_opts(qpid_opts)
-
-JSON_CONTENT_TYPE = 'application/json; charset=utf8'
-
-
-class ConsumerBase(object):
- """Consumer base class."""
-
- def __init__(self, session, callback, node_name, node_opts,
- link_name, link_opts):
- """Declare a queue on an amqp session.
-
- 'session' is the amqp session to use
- 'callback' is the callback to call when messages are received
- 'node_name' is the first part of the Qpid address string, before ';'
- 'node_opts' will be applied to the "x-declare" section of "node"
- in the address string.
- 'link_name' goes into the "name" field of the "link" in the address
- string
- 'link_opts' will be applied to the "x-declare" section of "link"
- in the address string.
- """
- self.callback = callback
- self.receiver = None
- self.session = None
-
- addr_opts = {
- "create": "always",
- "node": {
- "type": "topic",
- "x-declare": {
- "durable": True,
- "auto-delete": True,
- },
- },
- "link": {
- "name": link_name,
- "durable": True,
- "x-declare": {
- "durable": False,
- "auto-delete": True,
- "exclusive": False,
- },
- },
- }
- addr_opts["node"]["x-declare"].update(node_opts)
- addr_opts["link"]["x-declare"].update(link_opts)
-
- self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts))
-
- self.reconnect(session)
-
- def reconnect(self, session):
- """Re-declare the receiver after a qpid reconnect."""
- self.session = session
- self.receiver = session.receiver(self.address)
- self.receiver.capacity = 1
-
- def _unpack_json_msg(self, msg):
- """Load the JSON data in msg if msg.content_type indicates that it
- is necessary. Put the loaded data back into msg.content and
- update msg.content_type appropriately.
-
- A Qpid Message containing a dict will have a content_type of
- 'amqp/map', whereas one containing a string that needs to be converted
- back from JSON will have a content_type of JSON_CONTENT_TYPE.
-
- :param msg: a Qpid Message object
- :returns: None
- """
- if msg.content_type == JSON_CONTENT_TYPE:
- msg.content = jsonutils.loads(msg.content)
- msg.content_type = 'amqp/map'
-
- def consume(self):
- """Fetch the message and pass it to the callback object."""
- message = self.receiver.fetch()
- try:
- self._unpack_json_msg(message)
- msg = rpc_common.deserialize_msg(message.content)
- self.callback(msg)
- except Exception:
- LOG.exception(_("Failed to process message... skipping it."))
- finally:
- self.session.acknowledge(message)
-
- def get_receiver(self):
- return self.receiver
-
-
-class DirectConsumer(ConsumerBase):
- """Queue/consumer class for 'direct'."""
-
- def __init__(self, conf, session, msg_id, callback):
- """Init a 'direct' queue.
-
- 'session' is the amqp session to use
- 'msg_id' is the msg_id to listen on
- 'callback' is the callback to call when messages are received
- """
-
- super(DirectConsumer, self).__init__(session, callback,
- "%s/%s" % (msg_id, msg_id),
- {"type": "direct"},
- msg_id,
- {"exclusive": True})
-
-
-class TopicConsumer(ConsumerBase):
- """Consumer class for 'topic'."""
-
- def __init__(self, conf, session, topic, callback, name=None,
- exchange_name=None):
- """Init a 'topic' queue.
-
- :param session: the amqp session to use
- :param topic: is the topic to listen on
- :paramtype topic: str
- :param callback: the callback to call when messages are received
- :param name: optional queue name, defaults to topic
- """
-
- exchange_name = exchange_name or rpc_amqp.get_control_exchange(conf)
- super(TopicConsumer, self).__init__(session, callback,
- "%s/%s" % (exchange_name, topic),
- {}, name or topic, {})
-
-
-class FanoutConsumer(ConsumerBase):
- """Consumer class for 'fanout'."""
-
- def __init__(self, conf, session, topic, callback):
- """Init a 'fanout' queue.
-
- 'session' is the amqp session to use
- 'topic' is the topic to listen on
- 'callback' is the callback to call when messages are received
- """
-
- super(FanoutConsumer, self).__init__(
- session, callback,
- "%s_fanout" % topic,
- {"durable": False, "type": "fanout"},
- "%s_fanout_%s" % (topic, uuid.uuid4().hex),
- {"exclusive": True})
-
-
-class Publisher(object):
- """Base Publisher class."""
-
- def __init__(self, session, node_name, node_opts=None):
- """Init the Publisher class with the exchange_name, routing_key,
- and other options
- """
- self.sender = None
- self.session = session
-
- addr_opts = {
- "create": "always",
- "node": {
- "type": "topic",
- "x-declare": {
- "durable": False,
- # auto-delete isn't implemented for exchanges in qpid,
- # but put in here anyway
- "auto-delete": True,
- },
- },
- }
- if node_opts:
- addr_opts["node"]["x-declare"].update(node_opts)
-
- self.address = "%s ; %s" % (node_name, jsonutils.dumps(addr_opts))
-
- self.reconnect(session)
-
- def reconnect(self, session):
- """Re-establish the Sender after a reconnection."""
- self.sender = session.sender(self.address)
-
- def _pack_json_msg(self, msg):
- """Qpid cannot serialize dicts containing strings longer than 65535
- characters. This function dumps the message content to a JSON
- string, which Qpid is able to handle.
-
- :param msg: May be either a Qpid Message object or a bare dict.
- :returns: A Qpid Message with its content field JSON encoded.
- """
- try:
- msg.content = jsonutils.dumps(msg.content)
- except AttributeError:
- # Need to have a Qpid message so we can set the content_type.
- msg = qpid_messaging.Message(jsonutils.dumps(msg))
- msg.content_type = JSON_CONTENT_TYPE
- return msg
-
- def send(self, msg):
- """Send a message."""
- try:
- # Check if Qpid can encode the message
- check_msg = msg
- if not hasattr(check_msg, 'content_type'):
- check_msg = qpid_messaging.Message(msg)
- content_type = check_msg.content_type
- enc, dec = qpid_messaging.message.get_codec(content_type)
- enc(check_msg.content)
- except qpid_codec.CodecException:
- # This means the message couldn't be serialized as a dict.
- msg = self._pack_json_msg(msg)
- self.sender.send(msg)
-
-
-class DirectPublisher(Publisher):
- """Publisher class for 'direct'."""
- def __init__(self, conf, session, msg_id):
- """Init a 'direct' publisher."""
- super(DirectPublisher, self).__init__(session, msg_id,
- {"type": "Direct"})
-
-
-class TopicPublisher(Publisher):
- """Publisher class for 'topic'."""
- def __init__(self, conf, session, topic):
- """init a 'topic' publisher.
- """
- exchange_name = rpc_amqp.get_control_exchange(conf)
- super(TopicPublisher, self).__init__(session,
- "%s/%s" % (exchange_name, topic))
-
-
-class FanoutPublisher(Publisher):
- """Publisher class for 'fanout'."""
- def __init__(self, conf, session, topic):
- """init a 'fanout' publisher.
- """
- super(FanoutPublisher, self).__init__(
- session,
- "%s_fanout" % topic, {"type": "fanout"})
-
-
-class NotifyPublisher(Publisher):
- """Publisher class for notifications."""
- def __init__(self, conf, session, topic):
- """init a 'topic' publisher.
- """
- exchange_name = rpc_amqp.get_control_exchange(conf)
- super(NotifyPublisher, self).__init__(session,
- "%s/%s" % (exchange_name, topic),
- {"durable": True})
-
-
-class Connection(object):
- """Connection object."""
-
- pool = None
-
- def __init__(self, conf, server_params=None):
- if not qpid_messaging:
- raise ImportError("Failed to import qpid.messaging")
-
- self.session = None
- self.consumers = {}
- self.consumer_thread = None
- self.proxy_callbacks = []
- self.conf = conf
-
- if server_params and 'hostname' in server_params:
- # NOTE(russellb) This enables support for cast_to_server.
- server_params['qpid_hosts'] = [
- '%s:%d' % (server_params['hostname'],
- server_params.get('port', 5672))
- ]
-
- params = {
- 'qpid_hosts': self.conf.qpid_hosts,
- 'username': self.conf.qpid_username,
- 'password': self.conf.qpid_password,
- }
- params.update(server_params or {})
-
- self.brokers = params['qpid_hosts']
- self.username = params['username']
- self.password = params['password']
- self.connection_create(self.brokers[0])
- self.reconnect()
-
- def connection_create(self, broker):
- # Create the connection - this does not open the connection
- self.connection = qpid_messaging.Connection(broker)
-
- # Check if flags are set and if so set them for the connection
- # before we call open
- self.connection.username = self.username
- self.connection.password = self.password
-
- self.connection.sasl_mechanisms = self.conf.qpid_sasl_mechanisms
- # Reconnection is done by self.reconnect()
- self.connection.reconnect = False
- self.connection.heartbeat = self.conf.qpid_heartbeat
- self.connection.transport = self.conf.qpid_protocol
- self.connection.tcp_nodelay = self.conf.qpid_tcp_nodelay
-
- def _register_consumer(self, consumer):
- self.consumers[str(consumer.get_receiver())] = consumer
-
- def _lookup_consumer(self, receiver):
- return self.consumers[str(receiver)]
-
- def reconnect(self):
- """Handles reconnecting and re-establishing sessions and queues."""
- attempt = 0
- delay = 1
- while True:
- # Close the session if necessary
- if self.connection.opened():
- try:
- self.connection.close()
- except qpid_exceptions.ConnectionError:
- pass
-
- broker = self.brokers[attempt % len(self.brokers)]
- attempt += 1
-
- try:
- self.connection_create(broker)
- self.connection.open()
- except qpid_exceptions.ConnectionError as e:
- msg_dict = dict(e=e, delay=delay)
- msg = _("Unable to connect to AMQP server: %(e)s. "
- "Sleeping %(delay)s seconds") % msg_dict
- LOG.error(msg)
- time.sleep(delay)
- delay = min(2 * delay, 60)
- else:
- LOG.info(_('Connected to AMQP server on %s'), broker)
- break
-
- self.session = self.connection.session()
-
- if self.consumers:
- consumers = self.consumers
- self.consumers = {}
-
- for consumer in consumers.itervalues():
- consumer.reconnect(self.session)
- self._register_consumer(consumer)
-
- LOG.debug(_("Re-established AMQP queues"))
-
- def ensure(self, error_callback, method, *args, **kwargs):
- while True:
- try:
- return method(*args, **kwargs)
- except (qpid_exceptions.Empty,
- qpid_exceptions.ConnectionError) as e:
- if error_callback:
- error_callback(e)
- self.reconnect()
-
- def close(self):
- """Close/release this connection."""
- self.cancel_consumer_thread()
- self.wait_on_proxy_callbacks()
- try:
- self.connection.close()
- except Exception:
- # NOTE(dripton) Logging exceptions that happen during cleanup just
- # causes confusion; there's really nothing useful we can do with
- # them.
- pass
- self.connection = None
-
- def reset(self):
- """Reset a connection so it can be used again."""
- self.cancel_consumer_thread()
- self.wait_on_proxy_callbacks()
- self.session.close()
- self.session = self.connection.session()
- self.consumers = {}
-
- def declare_consumer(self, consumer_cls, topic, callback):
- """Create a Consumer using the class that was passed in and
- add it to our list of consumers
- """
- def _connect_error(exc):
- log_info = {'topic': topic, 'err_str': str(exc)}
- LOG.error(_("Failed to declare consumer for topic '%(topic)s': "
- "%(err_str)s") % log_info)
-
- def _declare_consumer():
- consumer = consumer_cls(self.conf, self.session, topic, callback)
- self._register_consumer(consumer)
- return consumer
-
- return self.ensure(_connect_error, _declare_consumer)
-
- def iterconsume(self, limit=None, timeout=None):
- """Return an iterator that will consume from all queues/consumers."""
-
- def _error_callback(exc):
- if isinstance(exc, qpid_exceptions.Empty):
- LOG.debug(_('Timed out waiting for RPC response: %s') %
- str(exc))
- raise rpc_common.Timeout()
- else:
- LOG.exception(_('Failed to consume message from queue: %s') %
- str(exc))
-
- def _consume():
- nxt_receiver = self.session.next_receiver(timeout=timeout)
- try:
- self._lookup_consumer(nxt_receiver).consume()
- except Exception:
- LOG.exception(_("Error processing message. Skipping it."))
-
- for iteration in itertools.count(0):
- if limit and iteration >= limit:
- raise StopIteration
- yield self.ensure(_error_callback, _consume)
-
- def cancel_consumer_thread(self):
- """Cancel a consumer thread."""
- if self.consumer_thread is not None:
- self.consumer_thread.kill()
- try:
- self.consumer_thread.wait()
- except greenlet.GreenletExit:
- pass
- self.consumer_thread = None
-
- def wait_on_proxy_callbacks(self):
- """Wait for all proxy callback threads to exit."""
- for proxy_cb in self.proxy_callbacks:
- proxy_cb.wait()
-
- def publisher_send(self, cls, topic, msg):
- """Send to a publisher based on the publisher class."""
-
- def _connect_error(exc):
- log_info = {'topic': topic, 'err_str': str(exc)}
- LOG.exception(_("Failed to publish message to topic "
- "'%(topic)s': %(err_str)s") % log_info)
-
- def _publisher_send():
- publisher = cls(self.conf, self.session, topic)
- publisher.send(msg)
-
- return self.ensure(_connect_error, _publisher_send)
-
- def declare_direct_consumer(self, topic, callback):
- """Create a 'direct' queue.
- In nova's use, this is generally a msg_id queue used for
- responses for call/multicall
- """
- self.declare_consumer(DirectConsumer, topic, callback)
-
- def declare_topic_consumer(self, topic, callback=None, queue_name=None,
- exchange_name=None):
- """Create a 'topic' consumer."""
- self.declare_consumer(functools.partial(TopicConsumer,
- name=queue_name,
- exchange_name=exchange_name,
- ),
- topic, callback)
-
- def declare_fanout_consumer(self, topic, callback):
- """Create a 'fanout' consumer."""
- self.declare_consumer(FanoutConsumer, topic, callback)
-
- def direct_send(self, msg_id, msg):
- """Send a 'direct' message."""
- self.publisher_send(DirectPublisher, msg_id, msg)
-
- def topic_send(self, topic, msg, timeout=None):
- """Send a 'topic' message."""
- #
- # We want to create a message with attributes, e.g. a TTL. We
- # don't really need to keep 'msg' in its JSON format any longer
- # so let's create an actual qpid message here and get some
- # value-add on the go.
- #
- # WARNING: Request timeout happens to be in the same units as
- # qpid's TTL (seconds). If this changes in the future, then this
- # will need to be altered accordingly.
- #
- qpid_message = qpid_messaging.Message(content=msg, ttl=timeout)
- self.publisher_send(TopicPublisher, topic, qpid_message)
-
- def fanout_send(self, topic, msg):
- """Send a 'fanout' message."""
- self.publisher_send(FanoutPublisher, topic, msg)
-
- def notify_send(self, topic, msg, **kwargs):
- """Send a notify message on a topic."""
- self.publisher_send(NotifyPublisher, topic, msg)
-
- def consume(self, limit=None):
- """Consume from all queues/consumers."""
- it = self.iterconsume(limit=limit)
- while True:
- try:
- it.next()
- except StopIteration:
- return
-
- def consume_in_thread(self):
- """Consumer from all queues/consumers in a greenthread."""
- def _consumer_thread():
- try:
- self.consume()
- except greenlet.GreenletExit:
- return
- if self.consumer_thread is None:
- self.consumer_thread = eventlet.spawn(_consumer_thread)
- return self.consumer_thread
-
- def create_consumer(self, topic, proxy, fanout=False):
- """Create a consumer that calls a method in a proxy object."""
- proxy_cb = rpc_amqp.ProxyCallback(
- self.conf, proxy,
- rpc_amqp.get_connection_pool(self.conf, Connection))
- self.proxy_callbacks.append(proxy_cb)
-
- if fanout:
- consumer = FanoutConsumer(self.conf, self.session, topic, proxy_cb)
- else:
- consumer = TopicConsumer(self.conf, self.session, topic, proxy_cb)
-
- self._register_consumer(consumer)
-
- return consumer
-
- def create_worker(self, topic, proxy, pool_name):
- """Create a worker that calls a method in a proxy object."""
- proxy_cb = rpc_amqp.ProxyCallback(
- self.conf, proxy,
- rpc_amqp.get_connection_pool(self.conf, Connection))
- self.proxy_callbacks.append(proxy_cb)
-
- consumer = TopicConsumer(self.conf, self.session, topic, proxy_cb,
- name=pool_name)
-
- self._register_consumer(consumer)
-
- return consumer
-
- def join_consumer_pool(self, callback, pool_name, topic,
- exchange_name=None):
- """Register as a member of a group of consumers for a given topic from
- the specified exchange.
-
- Exactly one member of a given pool will receive each message.
-
- A message will be delivered to multiple pools, if more than
- one is created.
- """
- callback_wrapper = rpc_amqp.CallbackWrapper(
- conf=self.conf,
- callback=callback,
- connection_pool=rpc_amqp.get_connection_pool(self.conf,
- Connection),
- )
- self.proxy_callbacks.append(callback_wrapper)
-
- consumer = TopicConsumer(conf=self.conf,
- session=self.session,
- topic=topic,
- callback=callback_wrapper,
- name=pool_name,
- exchange_name=exchange_name)
-
- self._register_consumer(consumer)
- return consumer
-
-
-def create_connection(conf, new=True):
- """Create a connection."""
- return rpc_amqp.create_connection(
- conf, new,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def multicall(conf, context, topic, msg, timeout=None):
- """Make a call that returns multiple times."""
- return rpc_amqp.multicall(
- conf, context, topic, msg, timeout,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def call(conf, context, topic, msg, timeout=None):
- """Sends a message on a topic and wait for a response."""
- return rpc_amqp.call(
- conf, context, topic, msg, timeout,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def cast(conf, context, topic, msg):
- """Sends a message on a topic without waiting for a response."""
- return rpc_amqp.cast(
- conf, context, topic, msg,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def fanout_cast(conf, context, topic, msg):
- """Sends a message on a fanout exchange without waiting for a response."""
- return rpc_amqp.fanout_cast(
- conf, context, topic, msg,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def cast_to_server(conf, context, server_params, topic, msg):
- """Sends a message on a topic to a specific server."""
- return rpc_amqp.cast_to_server(
- conf, context, server_params, topic, msg,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def fanout_cast_to_server(conf, context, server_params, topic, msg):
- """Sends a message on a fanout exchange to a specific server."""
- return rpc_amqp.fanout_cast_to_server(
- conf, context, server_params, topic, msg,
- rpc_amqp.get_connection_pool(conf, Connection))
-
-
-def notify(conf, context, topic, msg, envelope):
- """Sends a notification event on a topic."""
- return rpc_amqp.notify(conf, context, topic, msg,
- rpc_amqp.get_connection_pool(conf, Connection),
- envelope)
-
-
-def cleanup():
- return rpc_amqp.cleanup(Connection.pool)
diff --git a/openstack_dashboard/openstack/common/rpc/impl_zmq.py b/openstack_dashboard/openstack/common/rpc/impl_zmq.py
deleted file mode 100644
index 12f8a8bb..00000000
--- a/openstack_dashboard/openstack/common/rpc/impl_zmq.py
+++ /dev/null
@@ -1,848 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 Cloudscaling Group, 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 pprint
-import re
-import socket
-import sys
-import types
-import uuid
-
-import eventlet
-import greenlet
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common import excutils
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import importutils
-from openstack_dashboard.openstack.common import jsonutils
-from openstack_dashboard.openstack.common.rpc import common as rpc_common
-
-zmq = importutils.try_import('eventlet.green.zmq')
-
-# for convenience, are not modified.
-pformat = pprint.pformat
-Timeout = eventlet.timeout.Timeout
-LOG = rpc_common.LOG
-RemoteError = rpc_common.RemoteError
-RPCException = rpc_common.RPCException
-
-zmq_opts = [
- cfg.StrOpt('rpc_zmq_bind_address', default='*',
- help='ZeroMQ bind address. Should be a wildcard (*), '
- 'an ethernet interface, or IP. '
- 'The "host" option should point or resolve to this '
- 'address.'),
-
- # The module.Class to use for matchmaking.
- cfg.StrOpt(
- 'rpc_zmq_matchmaker',
- default=('openstack_dashboard.openstack.common.rpc.'
- 'matchmaker.MatchMakerLocalhost'),
- help='MatchMaker driver',
- ),
-
- # The following port is unassigned by IANA as of 2012-05-21
- cfg.IntOpt('rpc_zmq_port', default=9501,
- help='ZeroMQ receiver listening port'),
-
- cfg.IntOpt('rpc_zmq_contexts', default=1,
- help='Number of ZeroMQ contexts, defaults to 1'),
-
- cfg.IntOpt('rpc_zmq_topic_backlog', default=None,
- help='Maximum number of ingress messages to locally buffer '
- 'per topic. Default is unlimited.'),
-
- cfg.StrOpt('rpc_zmq_ipc_dir', default='/var/run/openstack',
- help='Directory for holding IPC sockets'),
-
- cfg.StrOpt('rpc_zmq_host', default=socket.gethostname(),
- help='Name of this node. Must be a valid hostname, FQDN, or '
- 'IP address. Must match "host" option, if running Nova.')
-]
-
-
-CONF = cfg.CONF
-CONF.register_opts(zmq_opts)
-
-ZMQ_CTX = None # ZeroMQ Context, must be global.
-matchmaker = None # memoized matchmaker object
-
-
-def _serialize(data):
- """
- Serialization wrapper
- We prefer using JSON, but it cannot encode all types.
- Error if a developer passes us bad data.
- """
- try:
- return jsonutils.dumps(data, ensure_ascii=True)
- except TypeError:
- with excutils.save_and_reraise_exception():
- LOG.error(_("JSON serialization failed."))
-
-
-def _deserialize(data):
- """
- Deserialization wrapper
- """
- LOG.debug(_("Deserializing: %s"), data)
- return jsonutils.loads(data)
-
-
-class ZmqSocket(object):
- """
- A tiny wrapper around ZeroMQ to simplify the send/recv protocol
- and connection management.
-
- Can be used as a Context (supports the 'with' statement).
- """
-
- def __init__(self, addr, zmq_type, bind=True, subscribe=None):
- self.sock = _get_ctxt().socket(zmq_type)
- self.addr = addr
- self.type = zmq_type
- self.subscriptions = []
-
- # Support failures on sending/receiving on wrong socket type.
- self.can_recv = zmq_type in (zmq.PULL, zmq.SUB)
- self.can_send = zmq_type in (zmq.PUSH, zmq.PUB)
- self.can_sub = zmq_type in (zmq.SUB, )
-
- # Support list, str, & None for subscribe arg (cast to list)
- do_sub = {
- list: subscribe,
- str: [subscribe],
- type(None): []
- }[type(subscribe)]
-
- for f in do_sub:
- self.subscribe(f)
-
- str_data = {'addr': addr, 'type': self.socket_s(),
- 'subscribe': subscribe, 'bind': bind}
-
- LOG.debug(_("Connecting to %(addr)s with %(type)s"), str_data)
- LOG.debug(_("-> Subscribed to %(subscribe)s"), str_data)
- LOG.debug(_("-> bind: %(bind)s"), str_data)
-
- try:
- if bind:
- self.sock.bind(addr)
- else:
- self.sock.connect(addr)
- except Exception:
- raise RPCException(_("Could not open socket."))
-
- def socket_s(self):
- """Get socket type as string."""
- t_enum = ('PUSH', 'PULL', 'PUB', 'SUB', 'REP', 'REQ', 'ROUTER',
- 'DEALER')
- return dict(map(lambda t: (getattr(zmq, t), t), t_enum))[self.type]
-
- def subscribe(self, msg_filter):
- """Subscribe."""
- if not self.can_sub:
- raise RPCException("Cannot subscribe on this socket.")
- LOG.debug(_("Subscribing to %s"), msg_filter)
-
- try:
- self.sock.setsockopt(zmq.SUBSCRIBE, msg_filter)
- except Exception:
- return
-
- self.subscriptions.append(msg_filter)
-
- def unsubscribe(self, msg_filter):
- """Unsubscribe."""
- if msg_filter not in self.subscriptions:
- return
- self.sock.setsockopt(zmq.UNSUBSCRIBE, msg_filter)
- self.subscriptions.remove(msg_filter)
-
- def close(self):
- if self.sock is None or self.sock.closed:
- return
-
- # We must unsubscribe, or we'll leak descriptors.
- if self.subscriptions:
- for f in self.subscriptions:
- try:
- self.sock.setsockopt(zmq.UNSUBSCRIBE, f)
- except Exception:
- pass
- self.subscriptions = []
-
- try:
- # Default is to linger
- self.sock.close()
- except Exception:
- # While this is a bad thing to happen,
- # it would be much worse if some of the code calling this
- # were to fail. For now, lets log, and later evaluate
- # if we can safely raise here.
- LOG.error("ZeroMQ socket could not be closed.")
- self.sock = None
-
- def recv(self, **kwargs):
- if not self.can_recv:
- raise RPCException(_("You cannot recv on this socket."))
- return self.sock.recv_multipart(**kwargs)
-
- def send(self, data, **kwargs):
- if not self.can_send:
- raise RPCException(_("You cannot send on this socket."))
- self.sock.send_multipart(data, **kwargs)
-
-
-class ZmqClient(object):
- """Client for ZMQ sockets."""
-
- def __init__(self, addr, socket_type=None, bind=False):
- if socket_type is None:
- socket_type = zmq.PUSH
- self.outq = ZmqSocket(addr, socket_type, bind=bind)
-
- def cast(self, msg_id, topic, data, envelope=False):
- msg_id = msg_id or 0
-
- if not envelope:
- self.outq.send(map(bytes,
- (msg_id, topic, 'cast', _serialize(data))))
- return
-
- rpc_envelope = rpc_common.serialize_msg(data[1], envelope)
- zmq_msg = reduce(lambda x, y: x + y, rpc_envelope.items())
- self.outq.send(map(bytes,
- (msg_id, topic, 'impl_zmq_v2', data[0]) + zmq_msg))
-
- def close(self):
- self.outq.close()
-
-
-class RpcContext(rpc_common.CommonRpcContext):
- """Context that supports replying to a rpc.call."""
- def __init__(self, **kwargs):
- self.replies = []
- super(RpcContext, self).__init__(**kwargs)
-
- def deepcopy(self):
- values = self.to_dict()
- values['replies'] = self.replies
- return self.__class__(**values)
-
- def reply(self, reply=None, failure=None, ending=False):
- if ending:
- return
- self.replies.append(reply)
-
- @classmethod
- def marshal(self, ctx):
- ctx_data = ctx.to_dict()
- return _serialize(ctx_data)
-
- @classmethod
- def unmarshal(self, data):
- return RpcContext.from_dict(_deserialize(data))
-
-
-class InternalContext(object):
- """Used by ConsumerBase as a private context for - methods."""
-
- def __init__(self, proxy):
- self.proxy = proxy
- self.msg_waiter = None
-
- def _get_response(self, ctx, proxy, topic, data):
- """Process a curried message and cast the result to topic."""
- LOG.debug(_("Running func with context: %s"), ctx.to_dict())
- data.setdefault('version', None)
- data.setdefault('args', {})
-
- try:
- result = proxy.dispatch(
- ctx, data['version'], data['method'],
- data.get('namespace'), **data['args'])
- return ConsumerBase.normalize_reply(result, ctx.replies)
- except greenlet.GreenletExit:
- # ignore these since they are just from shutdowns
- pass
- except rpc_common.ClientException as e:
- LOG.debug(_("Expected exception during message handling (%s)") %
- e._exc_info[1])
- return {'exc':
- rpc_common.serialize_remote_exception(e._exc_info,
- log_failure=False)}
- except Exception:
- LOG.error(_("Exception during message handling"))
- return {'exc':
- rpc_common.serialize_remote_exception(sys.exc_info())}
-
- def reply(self, ctx, proxy,
- msg_id=None, context=None, topic=None, msg=None):
- """Reply to a casted call."""
- # NOTE(ewindisch): context kwarg exists for Grizzly compat.
- # this may be able to be removed earlier than
- # 'I' if ConsumerBase.process were refactored.
- if type(msg) is list:
- payload = msg[-1]
- else:
- payload = msg
-
- response = ConsumerBase.normalize_reply(
- self._get_response(ctx, proxy, topic, payload),
- ctx.replies)
-
- LOG.debug(_("Sending reply"))
- _multi_send(_cast, ctx, topic, {
- 'method': '-process_reply',
- 'args': {
- 'msg_id': msg_id, # Include for Folsom compat.
- 'response': response
- }
- }, _msg_id=msg_id)
-
-
-class ConsumerBase(object):
- """Base Consumer."""
-
- def __init__(self):
- self.private_ctx = InternalContext(None)
-
- @classmethod
- def normalize_reply(self, result, replies):
- #TODO(ewindisch): re-evaluate and document this method.
- if isinstance(result, types.GeneratorType):
- return list(result)
- elif replies:
- return replies
- else:
- return [result]
-
- def process(self, proxy, ctx, data):
- data.setdefault('version', None)
- data.setdefault('args', {})
-
- # Method starting with - are
- # processed internally. (non-valid method name)
- method = data.get('method')
- if not method:
- LOG.error(_("RPC message did not include method."))
- return
-
- # Internal method
- # uses internal context for safety.
- if method == '-reply':
- self.private_ctx.reply(ctx, proxy, **data['args'])
- return
-
- proxy.dispatch(ctx, data['version'],
- data['method'], data.get('namespace'), **data['args'])
-
-
-class ZmqBaseReactor(ConsumerBase):
- """
- A consumer class implementing a
- centralized casting broker (PULL-PUSH)
- for RoundRobin requests.
- """
-
- def __init__(self, conf):
- super(ZmqBaseReactor, self).__init__()
-
- self.mapping = {}
- self.proxies = {}
- self.threads = []
- self.sockets = []
- self.subscribe = {}
-
- self.pool = eventlet.greenpool.GreenPool(conf.rpc_thread_pool_size)
-
- def register(self, proxy, in_addr, zmq_type_in, out_addr=None,
- zmq_type_out=None, in_bind=True, out_bind=True,
- subscribe=None):
-
- LOG.info(_("Registering reactor"))
-
- if zmq_type_in not in (zmq.PULL, zmq.SUB):
- raise RPCException("Bad input socktype")
-
- # Items push in.
- inq = ZmqSocket(in_addr, zmq_type_in, bind=in_bind,
- subscribe=subscribe)
-
- self.proxies[inq] = proxy
- self.sockets.append(inq)
-
- LOG.info(_("In reactor registered"))
-
- if not out_addr:
- return
-
- if zmq_type_out not in (zmq.PUSH, zmq.PUB):
- raise RPCException("Bad output socktype")
-
- # Items push out.
- outq = ZmqSocket(out_addr, zmq_type_out, bind=out_bind)
-
- self.mapping[inq] = outq
- self.mapping[outq] = inq
- self.sockets.append(outq)
-
- LOG.info(_("Out reactor registered"))
-
- def consume_in_thread(self):
- def _consume(sock):
- LOG.info(_("Consuming socket"))
- while True:
- self.consume(sock)
-
- for k in self.proxies.keys():
- self.threads.append(
- self.pool.spawn(_consume, k)
- )
-
- def wait(self):
- for t in self.threads:
- t.wait()
-
- def close(self):
- for s in self.sockets:
- s.close()
-
- for t in self.threads:
- t.kill()
-
-
-class ZmqProxy(ZmqBaseReactor):
- """
- A consumer class implementing a
- topic-based proxy, forwarding to
- IPC sockets.
- """
-
- def __init__(self, conf):
- super(ZmqProxy, self).__init__(conf)
- pathsep = set((os.path.sep or '', os.path.altsep or '', '/', '\\'))
- self.badchars = re.compile(r'[%s]' % re.escape(''.join(pathsep)))
-
- self.topic_proxy = {}
-
- def consume(self, sock):
- ipc_dir = CONF.rpc_zmq_ipc_dir
-
- data = sock.recv(copy=False)
- topic = data[1].bytes
-
- if topic.startswith('fanout~'):
- sock_type = zmq.PUB
- topic = topic.split('.', 1)[0]
- elif topic.startswith('zmq_replies'):
- sock_type = zmq.PUB
- else:
- sock_type = zmq.PUSH
-
- if topic not in self.topic_proxy:
- def publisher(waiter):
- LOG.info(_("Creating proxy for topic: %s"), topic)
-
- try:
- # The topic is received over the network,
- # don't trust this input.
- if self.badchars.search(topic) is not None:
- emsg = _("Topic contained dangerous characters.")
- LOG.warn(emsg)
- raise RPCException(emsg)
-
- out_sock = ZmqSocket("ipc://%s/zmq_topic_%s" %
- (ipc_dir, topic),
- sock_type, bind=True)
- except RPCException:
- waiter.send_exception(*sys.exc_info())
- return
-
- self.topic_proxy[topic] = eventlet.queue.LightQueue(
- CONF.rpc_zmq_topic_backlog)
- self.sockets.append(out_sock)
-
- # It takes some time for a pub socket to open,
- # before we can have any faith in doing a send() to it.
- if sock_type == zmq.PUB:
- eventlet.sleep(.5)
-
- waiter.send(True)
-
- while(True):
- data = self.topic_proxy[topic].get()
- out_sock.send(data, copy=False)
-
- wait_sock_creation = eventlet.event.Event()
- eventlet.spawn(publisher, wait_sock_creation)
-
- try:
- wait_sock_creation.wait()
- except RPCException:
- LOG.error(_("Topic socket file creation failed."))
- return
-
- try:
- self.topic_proxy[topic].put_nowait(data)
- except eventlet.queue.Full:
- LOG.error(_("Local per-topic backlog buffer full for topic "
- "%(topic)s. Dropping message.") % {'topic': topic})
-
- def consume_in_thread(self):
- """Runs the ZmqProxy service."""
- ipc_dir = CONF.rpc_zmq_ipc_dir
- consume_in = "tcp://%s:%s" % \
- (CONF.rpc_zmq_bind_address,
- CONF.rpc_zmq_port)
- consumption_proxy = InternalContext(None)
-
- try:
- os.makedirs(ipc_dir)
- except os.error:
- if not os.path.isdir(ipc_dir):
- with excutils.save_and_reraise_exception():
- LOG.error(_("Required IPC directory does not exist at"
- " %s") % (ipc_dir, ))
- try:
- self.register(consumption_proxy,
- consume_in,
- zmq.PULL,
- out_bind=True)
- except zmq.ZMQError:
- if os.access(ipc_dir, os.X_OK):
- with excutils.save_and_reraise_exception():
- LOG.error(_("Permission denied to IPC directory at"
- " %s") % (ipc_dir, ))
- with excutils.save_and_reraise_exception():
- LOG.error(_("Could not create ZeroMQ receiver daemon. "
- "Socket may already be in use."))
-
- super(ZmqProxy, self).consume_in_thread()
-
-
-def unflatten_envelope(packenv):
- """Unflattens the RPC envelope.
- Takes a list and returns a dictionary.
- i.e. [1,2,3,4] => {1: 2, 3: 4}
- """
- i = iter(packenv)
- h = {}
- try:
- while True:
- k = i.next()
- h[k] = i.next()
- except StopIteration:
- return h
-
-
-class ZmqReactor(ZmqBaseReactor):
- """
- A consumer class implementing a
- consumer for messages. Can also be
- used as a 1:1 proxy
- """
-
- def __init__(self, conf):
- super(ZmqReactor, self).__init__(conf)
-
- def consume(self, sock):
- #TODO(ewindisch): use zero-copy (i.e. references, not copying)
- data = sock.recv()
- LOG.debug(_("CONSUMER RECEIVED DATA: %s"), data)
- if sock in self.mapping:
- LOG.debug(_("ROUTER RELAY-OUT %(data)s") % {
- 'data': data})
- self.mapping[sock].send(data)
- return
-
- proxy = self.proxies[sock]
-
- if data[2] == 'cast': # Legacy protocol
- packenv = data[3]
-
- ctx, msg = _deserialize(packenv)
- request = rpc_common.deserialize_msg(msg)
- ctx = RpcContext.unmarshal(ctx)
- elif data[2] == 'impl_zmq_v2':
- packenv = data[4:]
-
- msg = unflatten_envelope(packenv)
- request = rpc_common.deserialize_msg(msg)
-
- # Unmarshal only after verifying the message.
- ctx = RpcContext.unmarshal(data[3])
- else:
- LOG.error(_("ZMQ Envelope version unsupported or unknown."))
- return
-
- self.pool.spawn_n(self.process, proxy, ctx, request)
-
-
-class Connection(rpc_common.Connection):
- """Manages connections and threads."""
-
- def __init__(self, conf):
- self.topics = []
- self.reactor = ZmqReactor(conf)
-
- def create_consumer(self, topic, proxy, fanout=False):
- # Register with matchmaker.
- _get_matchmaker().register(topic, CONF.rpc_zmq_host)
-
- # Subscription scenarios
- if fanout:
- sock_type = zmq.SUB
- subscribe = ('', fanout)[type(fanout) == str]
- topic = 'fanout~' + topic.split('.', 1)[0]
- else:
- sock_type = zmq.PULL
- subscribe = None
- topic = '.'.join((topic.split('.', 1)[0], CONF.rpc_zmq_host))
-
- if topic in self.topics:
- LOG.info(_("Skipping topic registration. Already registered."))
- return
-
- # Receive messages from (local) proxy
- inaddr = "ipc://%s/zmq_topic_%s" % \
- (CONF.rpc_zmq_ipc_dir, topic)
-
- LOG.debug(_("Consumer is a zmq.%s"),
- ['PULL', 'SUB'][sock_type == zmq.SUB])
-
- self.reactor.register(proxy, inaddr, sock_type,
- subscribe=subscribe, in_bind=False)
- self.topics.append(topic)
-
- def close(self):
- _get_matchmaker().stop_heartbeat()
- for topic in self.topics:
- _get_matchmaker().unregister(topic, CONF.rpc_zmq_host)
-
- self.reactor.close()
- self.topics = []
-
- def wait(self):
- self.reactor.wait()
-
- def consume_in_thread(self):
- _get_matchmaker().start_heartbeat()
- self.reactor.consume_in_thread()
-
-
-def _cast(addr, context, topic, msg, timeout=None, envelope=False,
- _msg_id=None):
- timeout_cast = timeout or CONF.rpc_cast_timeout
- payload = [RpcContext.marshal(context), msg]
-
- with Timeout(timeout_cast, exception=rpc_common.Timeout):
- try:
- conn = ZmqClient(addr)
-
- # assumes cast can't return an exception
- conn.cast(_msg_id, topic, payload, envelope)
- except zmq.ZMQError:
- raise RPCException("Cast failed. ZMQ Socket Exception")
- finally:
- if 'conn' in vars():
- conn.close()
-
-
-def _call(addr, context, topic, msg, timeout=None,
- envelope=False):
- # timeout_response is how long we wait for a response
- timeout = timeout or CONF.rpc_response_timeout
-
- # The msg_id is used to track replies.
- msg_id = uuid.uuid4().hex
-
- # Replies always come into the reply service.
- reply_topic = "zmq_replies.%s" % CONF.rpc_zmq_host
-
- LOG.debug(_("Creating payload"))
- # Curry the original request into a reply method.
- mcontext = RpcContext.marshal(context)
- payload = {
- 'method': '-reply',
- 'args': {
- 'msg_id': msg_id,
- 'topic': reply_topic,
- # TODO(ewindisch): safe to remove mcontext in I.
- 'msg': [mcontext, msg]
- }
- }
-
- LOG.debug(_("Creating queue socket for reply waiter"))
-
- # Messages arriving async.
- # TODO(ewindisch): have reply consumer with dynamic subscription mgmt
- with Timeout(timeout, exception=rpc_common.Timeout):
- try:
- msg_waiter = ZmqSocket(
- "ipc://%s/zmq_topic_zmq_replies.%s" %
- (CONF.rpc_zmq_ipc_dir,
- CONF.rpc_zmq_host),
- zmq.SUB, subscribe=msg_id, bind=False
- )
-
- LOG.debug(_("Sending cast"))
- _cast(addr, context, topic, payload, envelope)
-
- LOG.debug(_("Cast sent; Waiting reply"))
- # Blocks until receives reply
- msg = msg_waiter.recv()
- LOG.debug(_("Received message: %s"), msg)
- LOG.debug(_("Unpacking response"))
-
- if msg[2] == 'cast': # Legacy version
- raw_msg = _deserialize(msg[-1])[-1]
- elif msg[2] == 'impl_zmq_v2':
- rpc_envelope = unflatten_envelope(msg[4:])
- raw_msg = rpc_common.deserialize_msg(rpc_envelope)
- else:
- raise rpc_common.UnsupportedRpcEnvelopeVersion(
- _("Unsupported or unknown ZMQ envelope returned."))
-
- responses = raw_msg['args']['response']
- # ZMQError trumps the Timeout error.
- except zmq.ZMQError:
- raise RPCException("ZMQ Socket Error")
- except (IndexError, KeyError):
- raise RPCException(_("RPC Message Invalid."))
- finally:
- if 'msg_waiter' in vars():
- msg_waiter.close()
-
- # It seems we don't need to do all of the following,
- # but perhaps it would be useful for multicall?
- # One effect of this is that we're checking all
- # responses for Exceptions.
- for resp in responses:
- if isinstance(resp, types.DictType) and 'exc' in resp:
- raise rpc_common.deserialize_remote_exception(CONF, resp['exc'])
-
- return responses[-1]
-
-
-def _multi_send(method, context, topic, msg, timeout=None,
- envelope=False, _msg_id=None):
- """
- Wraps the sending of messages,
- dispatches to the matchmaker and sends
- message to all relevant hosts.
- """
- conf = CONF
- LOG.debug(_("%(msg)s") % {'msg': ' '.join(map(pformat, (topic, msg)))})
-
- queues = _get_matchmaker().queues(topic)
- LOG.debug(_("Sending message(s) to: %s"), queues)
-
- # Don't stack if we have no matchmaker results
- if not queues:
- LOG.warn(_("No matchmaker results. Not casting."))
- # While not strictly a timeout, callers know how to handle
- # this exception and a timeout isn't too big a lie.
- raise rpc_common.Timeout(_("No match from matchmaker."))
-
- # This supports brokerless fanout (addresses > 1)
- for queue in queues:
- (_topic, ip_addr) = queue
- _addr = "tcp://%s:%s" % (ip_addr, conf.rpc_zmq_port)
-
- if method.__name__ == '_cast':
- eventlet.spawn_n(method, _addr, context,
- _topic, msg, timeout, envelope,
- _msg_id)
- return
- return method(_addr, context, _topic, msg, timeout,
- envelope)
-
-
-def create_connection(conf, new=True):
- return Connection(conf)
-
-
-def multicall(conf, *args, **kwargs):
- """Multiple calls."""
- return _multi_send(_call, *args, **kwargs)
-
-
-def call(conf, *args, **kwargs):
- """Send a message, expect a response."""
- data = _multi_send(_call, *args, **kwargs)
- return data[-1]
-
-
-def cast(conf, *args, **kwargs):
- """Send a message expecting no reply."""
- _multi_send(_cast, *args, **kwargs)
-
-
-def fanout_cast(conf, context, topic, msg, **kwargs):
- """Send a message to all listening and expect no reply."""
- # NOTE(ewindisch): fanout~ is used because it avoid splitting on .
- # and acts as a non-subtle hint to the matchmaker and ZmqProxy.
- _multi_send(_cast, context, 'fanout~' + str(topic), msg, **kwargs)
-
-
-def notify(conf, context, topic, msg, envelope):
- """
- Send notification event.
- Notifications are sent to topic-priority.
- This differs from the AMQP drivers which send to topic.priority.
- """
- # NOTE(ewindisch): dot-priority in rpc notifier does not
- # work with our assumptions.
- topic = topic.replace('.', '-')
- cast(conf, context, topic, msg, envelope=envelope)
-
-
-def cleanup():
- """Clean up resources in use by implementation."""
- global ZMQ_CTX
- if ZMQ_CTX:
- ZMQ_CTX.term()
- ZMQ_CTX = None
-
- global matchmaker
- matchmaker = None
-
-
-def _get_ctxt():
- if not zmq:
- raise ImportError("Failed to import eventlet.green.zmq")
-
- global ZMQ_CTX
- if not ZMQ_CTX:
- ZMQ_CTX = zmq.Context(CONF.rpc_zmq_contexts)
- return ZMQ_CTX
-
-
-def _get_matchmaker(*args, **kwargs):
- global matchmaker
- if not matchmaker:
- mm = CONF.rpc_zmq_matchmaker
- if mm.endswith('matchmaker.MatchMakerRing'):
- mm.replace('matchmaker', 'matchmaker_ring')
- LOG.warn(_('rpc_zmq_matchmaker = %(orig)s is deprecated; use'
- ' %(new)s instead') % dict(
- orig=CONF.rpc_zmq_matchmaker, new=mm))
- matchmaker = importutils.import_object(mm, *args, **kwargs)
- return matchmaker
diff --git a/openstack_dashboard/openstack/common/rpc/matchmaker.py b/openstack_dashboard/openstack/common/rpc/matchmaker.py
deleted file mode 100644
index a1f4be13..00000000
--- a/openstack_dashboard/openstack/common/rpc/matchmaker.py
+++ /dev/null
@@ -1,348 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 Cloudscaling Group, 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 MatchMaker classes should except a Topic or Fanout exchange key and
-return keys for direct exchanges, per (approximate) AMQP parlance.
-"""
-
-import contextlib
-
-import eventlet
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import log as logging
-
-
-matchmaker_opts = [
- cfg.IntOpt('matchmaker_heartbeat_freq',
- default=300,
- help='Heartbeat frequency'),
- cfg.IntOpt('matchmaker_heartbeat_ttl',
- default=600,
- help='Heartbeat time-to-live.'),
-]
-
-CONF = cfg.CONF
-CONF.register_opts(matchmaker_opts)
-LOG = logging.getLogger(__name__)
-contextmanager = contextlib.contextmanager
-
-
-class MatchMakerException(Exception):
- """Signified a match could not be found."""
- message = _("Match not found by MatchMaker.")
-
-
-class Exchange(object):
- """
- Implements lookups.
- Subclass this to support hashtables, dns, etc.
- """
- def __init__(self):
- pass
-
- def run(self, key):
- raise NotImplementedError()
-
-
-class Binding(object):
- """
- A binding on which to perform a lookup.
- """
- def __init__(self):
- pass
-
- def test(self, key):
- raise NotImplementedError()
-
-
-class MatchMakerBase(object):
- """
- Match Maker Base Class.
- Build off HeartbeatMatchMakerBase if building a
- heartbeat-capable MatchMaker.
- """
- def __init__(self):
- # Array of tuples. Index [2] toggles negation, [3] is last-if-true
- self.bindings = []
-
- self.no_heartbeat_msg = _('Matchmaker does not implement '
- 'registration or heartbeat.')
-
- def register(self, key, host):
- """
- Register a host on a backend.
- Heartbeats, if applicable, may keepalive registration.
- """
- pass
-
- def ack_alive(self, key, host):
- """
- Acknowledge that a key.host is alive.
- Used internally for updating heartbeats,
- but may also be used publically to acknowledge
- a system is alive (i.e. rpc message successfully
- sent to host)
- """
- pass
-
- def is_alive(self, topic, host):
- """
- Checks if a host is alive.
- """
- pass
-
- def expire(self, topic, host):
- """
- Explicitly expire a host's registration.
- """
- pass
-
- def send_heartbeats(self):
- """
- Send all heartbeats.
- Use start_heartbeat to spawn a heartbeat greenthread,
- which loops this method.
- """
- pass
-
- def unregister(self, key, host):
- """
- Unregister a topic.
- """
- pass
-
- def start_heartbeat(self):
- """
- Spawn heartbeat greenthread.
- """
- pass
-
- def stop_heartbeat(self):
- """
- Destroys the heartbeat greenthread.
- """
- pass
-
- def add_binding(self, binding, rule, last=True):
- self.bindings.append((binding, rule, False, last))
-
- #NOTE(ewindisch): kept the following method in case we implement the
- # underlying support.
- #def add_negate_binding(self, binding, rule, last=True):
- # self.bindings.append((binding, rule, True, last))
-
- def queues(self, key):
- workers = []
-
- # bit is for negate bindings - if we choose to implement it.
- # last stops processing rules if this matches.
- for (binding, exchange, bit, last) in self.bindings:
- if binding.test(key):
- workers.extend(exchange.run(key))
-
- # Support last.
- if last:
- return workers
- return workers
-
-
-class HeartbeatMatchMakerBase(MatchMakerBase):
- """
- Base for a heart-beat capable MatchMaker.
- Provides common methods for registering,
- unregistering, and maintaining heartbeats.
- """
- def __init__(self):
- self.hosts = set()
- self._heart = None
- self.host_topic = {}
-
- super(HeartbeatMatchMakerBase, self).__init__()
-
- def send_heartbeats(self):
- """
- Send all heartbeats.
- Use start_heartbeat to spawn a heartbeat greenthread,
- which loops this method.
- """
- for key, host in self.host_topic:
- self.ack_alive(key, host)
-
- def ack_alive(self, key, host):
- """
- Acknowledge that a host.topic is alive.
- Used internally for updating heartbeats,
- but may also be used publically to acknowledge
- a system is alive (i.e. rpc message successfully
- sent to host)
- """
- raise NotImplementedError("Must implement ack_alive")
-
- def backend_register(self, key, host):
- """
- Implements registration logic.
- Called by register(self,key,host)
- """
- raise NotImplementedError("Must implement backend_register")
-
- def backend_unregister(self, key, key_host):
- """
- Implements de-registration logic.
- Called by unregister(self,key,host)
- """
- raise NotImplementedError("Must implement backend_unregister")
-
- def register(self, key, host):
- """
- Register a host on a backend.
- Heartbeats, if applicable, may keepalive registration.
- """
- self.hosts.add(host)
- self.host_topic[(key, host)] = host
- key_host = '.'.join((key, host))
-
- self.backend_register(key, key_host)
-
- self.ack_alive(key, host)
-
- def unregister(self, key, host):
- """
- Unregister a topic.
- """
- if (key, host) in self.host_topic:
- del self.host_topic[(key, host)]
-
- self.hosts.discard(host)
- self.backend_unregister(key, '.'.join((key, host)))
-
- LOG.info(_("Matchmaker unregistered: %(key)s, %(host)s"),
- {'key': key, 'host': host})
-
- def start_heartbeat(self):
- """
- Implementation of MatchMakerBase.start_heartbeat
- Launches greenthread looping send_heartbeats(),
- yielding for CONF.matchmaker_heartbeat_freq seconds
- between iterations.
- """
- if not self.hosts:
- raise MatchMakerException(
- _("Register before starting heartbeat."))
-
- def do_heartbeat():
- while True:
- self.send_heartbeats()
- eventlet.sleep(CONF.matchmaker_heartbeat_freq)
-
- self._heart = eventlet.spawn(do_heartbeat)
-
- def stop_heartbeat(self):
- """
- Destroys the heartbeat greenthread.
- """
- if self._heart:
- self._heart.kill()
-
-
-class DirectBinding(Binding):
- """
- Specifies a host in the key via a '.' character
- Although dots are used in the key, the behavior here is
- that it maps directly to a host, thus direct.
- """
- def test(self, key):
- if '.' in key:
- return True
- return False
-
-
-class TopicBinding(Binding):
- """
- Where a 'bare' key without dots.
- AMQP generally considers topic exchanges to be those *with* dots,
- but we deviate here in terminology as the behavior here matches
- that of a topic exchange (whereas where there are dots, behavior
- matches that of a direct exchange.
- """
- def test(self, key):
- if '.' not in key:
- return True
- return False
-
-
-class FanoutBinding(Binding):
- """Match on fanout keys, where key starts with 'fanout.' string."""
- def test(self, key):
- if key.startswith('fanout~'):
- return True
- return False
-
-
-class StubExchange(Exchange):
- """Exchange that does nothing."""
- def run(self, key):
- return [(key, None)]
-
-
-class LocalhostExchange(Exchange):
- """Exchange where all direct topics are local."""
- def __init__(self, host='localhost'):
- self.host = host
- super(Exchange, self).__init__()
-
- def run(self, key):
- return [('.'.join((key.split('.')[0], self.host)), self.host)]
-
-
-class DirectExchange(Exchange):
- """
- Exchange where all topic keys are split, sending to second half.
- i.e. "compute.host" sends a message to "compute.host" running on "host"
- """
- def __init__(self):
- super(Exchange, self).__init__()
-
- def run(self, key):
- e = key.split('.', 1)[1]
- return [(key, e)]
-
-
-class MatchMakerLocalhost(MatchMakerBase):
- """
- Match Maker where all bare topics resolve to localhost.
- Useful for testing.
- """
- def __init__(self, host='localhost'):
- super(MatchMakerLocalhost, self).__init__()
- self.add_binding(FanoutBinding(), LocalhostExchange(host))
- self.add_binding(DirectBinding(), DirectExchange())
- self.add_binding(TopicBinding(), LocalhostExchange(host))
-
-
-class MatchMakerStub(MatchMakerBase):
- """
- Match Maker where topics are untouched.
- Useful for testing, or for AMQP/brokered queues.
- Will not work where knowledge of hosts is known (i.e. zeromq)
- """
- def __init__(self):
- super(MatchMakerStub, self).__init__()
-
- self.add_binding(FanoutBinding(), StubExchange())
- self.add_binding(DirectBinding(), StubExchange())
- self.add_binding(TopicBinding(), StubExchange())
diff --git a/openstack_dashboard/openstack/common/rpc/matchmaker_redis.py b/openstack_dashboard/openstack/common/rpc/matchmaker_redis.py
deleted file mode 100644
index ff77c837..00000000
--- a/openstack_dashboard/openstack/common/rpc/matchmaker_redis.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Cloudscaling Group, 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 MatchMaker classes should accept a Topic or Fanout exchange key and
-return keys for direct exchanges, per (approximate) AMQP parlance.
-"""
-
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common import importutils
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common.rpc import matchmaker as mm_common
-
-redis = importutils.try_import('redis')
-
-
-matchmaker_redis_opts = [
- cfg.StrOpt('host',
- default='127.0.0.1',
- help='Host to locate redis'),
- cfg.IntOpt('port',
- default=6379,
- help='Use this port to connect to redis host.'),
- cfg.StrOpt('password',
- default=None,
- help='Password for Redis server. (optional)'),
-]
-
-CONF = cfg.CONF
-opt_group = cfg.OptGroup(name='matchmaker_redis',
- title='Options for Redis-based MatchMaker')
-CONF.register_group(opt_group)
-CONF.register_opts(matchmaker_redis_opts, opt_group)
-LOG = logging.getLogger(__name__)
-
-
-class RedisExchange(mm_common.Exchange):
- def __init__(self, matchmaker):
- self.matchmaker = matchmaker
- self.redis = matchmaker.redis
- super(RedisExchange, self).__init__()
-
-
-class RedisTopicExchange(RedisExchange):
- """
- Exchange where all topic keys are split, sending to second half.
- i.e. "compute.host" sends a message to "compute" running on "host"
- """
- def run(self, topic):
- while True:
- member_name = self.redis.srandmember(topic)
-
- if not member_name:
- # If this happens, there are no
- # longer any members.
- break
-
- if not self.matchmaker.is_alive(topic, member_name):
- continue
-
- host = member_name.split('.', 1)[1]
- return [(member_name, host)]
- return []
-
-
-class RedisFanoutExchange(RedisExchange):
- """
- Return a list of all hosts.
- """
- def run(self, topic):
- topic = topic.split('~', 1)[1]
- hosts = self.redis.smembers(topic)
- good_hosts = filter(
- lambda host: self.matchmaker.is_alive(topic, host), hosts)
-
- return [(x, x.split('.', 1)[1]) for x in good_hosts]
-
-
-class MatchMakerRedis(mm_common.HeartbeatMatchMakerBase):
- """
- MatchMaker registering and looking-up hosts with a Redis server.
- """
- def __init__(self):
- super(MatchMakerRedis, self).__init__()
-
- if not redis:
- raise ImportError("Failed to import module redis.")
-
- self.redis = redis.StrictRedis(
- host=CONF.matchmaker_redis.host,
- port=CONF.matchmaker_redis.port,
- password=CONF.matchmaker_redis.password)
-
- self.add_binding(mm_common.FanoutBinding(), RedisFanoutExchange(self))
- self.add_binding(mm_common.DirectBinding(), mm_common.DirectExchange())
- self.add_binding(mm_common.TopicBinding(), RedisTopicExchange(self))
-
- def ack_alive(self, key, host):
- topic = "%s.%s" % (key, host)
- if not self.redis.expire(topic, CONF.matchmaker_heartbeat_ttl):
- # If we could not update the expiration, the key
- # might have been pruned. Re-register, creating a new
- # key in Redis.
- self.register(self.topic_host[host], host)
-
- def is_alive(self, topic, host):
- if self.redis.ttl(host) == -1:
- self.expire(topic, host)
- return False
- return True
-
- def expire(self, topic, host):
- with self.redis.pipeline() as pipe:
- pipe.multi()
- pipe.delete(host)
- pipe.srem(topic, host)
- pipe.execute()
-
- def backend_register(self, key, key_host):
- with self.redis.pipeline() as pipe:
- pipe.multi()
- pipe.sadd(key, key_host)
-
- # No value is needed, we just
- # care if it exists. Sets aren't viable
- # because only keys can expire.
- pipe.set(key_host, '')
-
- pipe.execute()
-
- def backend_unregister(self, key, key_host):
- with self.redis.pipeline() as pipe:
- pipe.multi()
- pipe.srem(key, key_host)
- pipe.delete(key_host)
- pipe.execute()
diff --git a/openstack_dashboard/openstack/common/rpc/matchmaker_ring.py b/openstack_dashboard/openstack/common/rpc/matchmaker_ring.py
deleted file mode 100644
index 61df411d..00000000
--- a/openstack_dashboard/openstack/common/rpc/matchmaker_ring.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011-2013 Cloudscaling Group, 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 MatchMaker classes should except a Topic or Fanout exchange key and
-return keys for direct exchanges, per (approximate) AMQP parlance.
-"""
-
-import itertools
-import json
-
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common.rpc import matchmaker as mm
-
-
-matchmaker_opts = [
- # Matchmaker ring file
- cfg.StrOpt('ringfile',
- deprecated_name='matchmaker_ringfile',
- deprecated_group='DEFAULT',
- default='/etc/oslo/matchmaker_ring.json',
- help='Matchmaker ring file (JSON)'),
-]
-
-CONF = cfg.CONF
-CONF.register_opts(matchmaker_opts, 'matchmaker_ring')
-LOG = logging.getLogger(__name__)
-
-
-class RingExchange(mm.Exchange):
- """
- Match Maker where hosts are loaded from a static file containing
- a hashmap (JSON formatted).
-
- __init__ takes optional ring dictionary argument, otherwise
- loads the ringfile from CONF.mathcmaker_ringfile.
- """
- def __init__(self, ring=None):
- super(RingExchange, self).__init__()
-
- if ring:
- self.ring = ring
- else:
- fh = open(CONF.matchmaker_ring.ringfile, 'r')
- self.ring = json.load(fh)
- fh.close()
-
- self.ring0 = {}
- for k in self.ring.keys():
- self.ring0[k] = itertools.cycle(self.ring[k])
-
- def _ring_has(self, key):
- if key in self.ring0:
- return True
- return False
-
-
-class RoundRobinRingExchange(RingExchange):
- """A Topic Exchange based on a hashmap."""
- def __init__(self, ring=None):
- super(RoundRobinRingExchange, self).__init__(ring)
-
- def run(self, key):
- if not self._ring_has(key):
- LOG.warn(
- _("No key defining hosts for topic '%s', "
- "see ringfile") % (key, )
- )
- return []
- host = next(self.ring0[key])
- return [(key + '.' + host, host)]
-
-
-class FanoutRingExchange(RingExchange):
- """Fanout Exchange based on a hashmap."""
- def __init__(self, ring=None):
- super(FanoutRingExchange, self).__init__(ring)
-
- def run(self, key):
- # Assume starts with "fanout~", strip it for lookup.
- nkey = key.split('fanout~')[1:][0]
- if not self._ring_has(nkey):
- LOG.warn(
- _("No key defining hosts for topic '%s', "
- "see ringfile") % (nkey, )
- )
- return []
- return map(lambda x: (key + '.' + x, x), self.ring[nkey])
-
-
-class MatchMakerRing(mm.MatchMakerBase):
- """
- Match Maker where hosts are loaded from a static hashmap.
- """
- def __init__(self, ring=None):
- super(MatchMakerRing, self).__init__()
- self.add_binding(mm.FanoutBinding(), FanoutRingExchange(ring))
- self.add_binding(mm.DirectBinding(), mm.DirectExchange())
- self.add_binding(mm.TopicBinding(), RoundRobinRingExchange(ring))
diff --git a/openstack_dashboard/openstack/common/rpc/proxy.py b/openstack_dashboard/openstack/common/rpc/proxy.py
deleted file mode 100644
index da6b9fcc..00000000
--- a/openstack_dashboard/openstack/common/rpc/proxy.py
+++ /dev/null
@@ -1,221 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012-2013 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-A helper class for proxy objects to remote APIs.
-
-For more information about rpc API version numbers, see:
- rpc/dispatcher.py
-"""
-
-
-from openstack_dashboard.openstack.common import rpc
-from openstack_dashboard.openstack.common.rpc import common as rpc_common
-from openstack_dashboard.openstack.common.rpc import serializer as rpc_serializer
-
-
-class RpcProxy(object):
- """A helper class for rpc clients.
-
- This class is a wrapper around the RPC client API. It allows you to
- specify the topic and API version in a single place. This is intended to
- be used as a base class for a class that implements the client side of an
- rpc API.
- """
-
- # The default namespace, which can be overriden in a subclass.
- RPC_API_NAMESPACE = None
-
- def __init__(self, topic, default_version, version_cap=None,
- serializer=None):
- """Initialize an RpcProxy.
-
- :param topic: The topic to use for all messages.
- :param default_version: The default API version to request in all
- outgoing messages. This can be overridden on a per-message
- basis.
- :param version_cap: Optionally cap the maximum version used for sent
- messages.
- :param serializer: Optionaly (de-)serialize entities with a
- provided helper.
- """
- self.topic = topic
- self.default_version = default_version
- self.version_cap = version_cap
- if serializer is None:
- serializer = rpc_serializer.NoOpSerializer()
- self.serializer = serializer
- super(RpcProxy, self).__init__()
-
- def _set_version(self, msg, vers):
- """Helper method to set the version in a message.
-
- :param msg: The message having a version added to it.
- :param vers: The version number to add to the message.
- """
- v = vers if vers else self.default_version
- if (self.version_cap and not
- rpc_common.version_is_compatible(self.version_cap, v)):
- raise rpc_common.RpcVersionCapError(version=self.version_cap)
- msg['version'] = v
-
- def _get_topic(self, topic):
- """Return the topic to use for a message."""
- return topic if topic else self.topic
-
- @staticmethod
- def make_namespaced_msg(method, namespace, **kwargs):
- return {'method': method, 'namespace': namespace, 'args': kwargs}
-
- def make_msg(self, method, **kwargs):
- return self.make_namespaced_msg(method, self.RPC_API_NAMESPACE,
- **kwargs)
-
- def _serialize_msg_args(self, context, kwargs):
- """Helper method called to serialize message arguments.
-
- This calls our serializer on each argument, returning a new
- set of args that have been serialized.
-
- :param context: The request context
- :param kwargs: The arguments to serialize
- :returns: A new set of serialized arguments
- """
- new_kwargs = dict()
- for argname, arg in kwargs.iteritems():
- new_kwargs[argname] = self.serializer.serialize_entity(context,
- arg)
- return new_kwargs
-
- def call(self, context, msg, topic=None, version=None, timeout=None):
- """rpc.call() a remote method.
-
- :param context: The request context
- :param msg: The message to send, including the method and args.
- :param topic: Override the topic for this message.
- :param version: (Optional) Override the requested API version in this
- message.
- :param timeout: (Optional) A timeout to use when waiting for the
- response. If no timeout is specified, a default timeout will be
- used that is usually sufficient.
-
- :returns: The return value from the remote method.
- """
- self._set_version(msg, version)
- msg['args'] = self._serialize_msg_args(context, msg['args'])
- real_topic = self._get_topic(topic)
- try:
- result = rpc.call(context, real_topic, msg, timeout)
- return self.serializer.deserialize_entity(context, result)
- except rpc.common.Timeout as exc:
- raise rpc.common.Timeout(
- exc.info, real_topic, msg.get('method'))
-
- def multicall(self, context, msg, topic=None, version=None, timeout=None):
- """rpc.multicall() a remote method.
-
- :param context: The request context
- :param msg: The message to send, including the method and args.
- :param topic: Override the topic for this message.
- :param version: (Optional) Override the requested API version in this
- message.
- :param timeout: (Optional) A timeout to use when waiting for the
- response. If no timeout is specified, a default timeout will be
- used that is usually sufficient.
-
- :returns: An iterator that lets you process each of the returned values
- from the remote method as they arrive.
- """
- self._set_version(msg, version)
- msg['args'] = self._serialize_msg_args(context, msg['args'])
- real_topic = self._get_topic(topic)
- try:
- result = rpc.multicall(context, real_topic, msg, timeout)
- return self.serializer.deserialize_entity(context, result)
- except rpc.common.Timeout as exc:
- raise rpc.common.Timeout(
- exc.info, real_topic, msg.get('method'))
-
- def cast(self, context, msg, topic=None, version=None):
- """rpc.cast() a remote method.
-
- :param context: The request context
- :param msg: The message to send, including the method and args.
- :param topic: Override the topic for this message.
- :param version: (Optional) Override the requested API version in this
- message.
-
- :returns: None. rpc.cast() does not wait on any return value from the
- remote method.
- """
- self._set_version(msg, version)
- msg['args'] = self._serialize_msg_args(context, msg['args'])
- rpc.cast(context, self._get_topic(topic), msg)
-
- def fanout_cast(self, context, msg, topic=None, version=None):
- """rpc.fanout_cast() a remote method.
-
- :param context: The request context
- :param msg: The message to send, including the method and args.
- :param topic: Override the topic for this message.
- :param version: (Optional) Override the requested API version in this
- message.
-
- :returns: None. rpc.fanout_cast() does not wait on any return value
- from the remote method.
- """
- self._set_version(msg, version)
- msg['args'] = self._serialize_msg_args(context, msg['args'])
- rpc.fanout_cast(context, self._get_topic(topic), msg)
-
- def cast_to_server(self, context, server_params, msg, topic=None,
- version=None):
- """rpc.cast_to_server() a remote method.
-
- :param context: The request context
- :param server_params: Server parameters. See rpc.cast_to_server() for
- details.
- :param msg: The message to send, including the method and args.
- :param topic: Override the topic for this message.
- :param version: (Optional) Override the requested API version in this
- message.
-
- :returns: None. rpc.cast_to_server() does not wait on any
- return values.
- """
- self._set_version(msg, version)
- msg['args'] = self._serialize_msg_args(context, msg['args'])
- rpc.cast_to_server(context, server_params, self._get_topic(topic), msg)
-
- def fanout_cast_to_server(self, context, server_params, msg, topic=None,
- version=None):
- """rpc.fanout_cast_to_server() a remote method.
-
- :param context: The request context
- :param server_params: Server parameters. See rpc.cast_to_server() for
- details.
- :param msg: The message to send, including the method and args.
- :param topic: Override the topic for this message.
- :param version: (Optional) Override the requested API version in this
- message.
-
- :returns: None. rpc.fanout_cast_to_server() does not wait on any
- return values.
- """
- self._set_version(msg, version)
- msg['args'] = self._serialize_msg_args(context, msg['args'])
- rpc.fanout_cast_to_server(context, server_params,
- self._get_topic(topic), msg)
diff --git a/openstack_dashboard/openstack/common/rpc/serializer.py b/openstack_dashboard/openstack/common/rpc/serializer.py
deleted file mode 100644
index 76c68310..00000000
--- a/openstack_dashboard/openstack/common/rpc/serializer.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2013 IBM Corp.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Provides the definition of an RPC serialization handler"""
-
-import abc
-
-
-class Serializer(object):
- """Generic (de-)serialization definition base class."""
- __metaclass__ = abc.ABCMeta
-
- @abc.abstractmethod
- def serialize_entity(self, context, entity):
- """Serialize something to primitive form.
-
- :param context: Security context
- :param entity: Entity to be serialized
- :returns: Serialized form of entity
- """
- pass
-
- @abc.abstractmethod
- def deserialize_entity(self, context, entity):
- """Deserialize something from primitive form.
-
- :param context: Security context
- :param entity: Primitive to be deserialized
- :returns: Deserialized form of entity
- """
- pass
-
-
-class NoOpSerializer(Serializer):
- """A serializer that does nothing."""
-
- def serialize_entity(self, context, entity):
- return entity
-
- def deserialize_entity(self, context, entity):
- return entity
diff --git a/openstack_dashboard/openstack/common/rpc/service.py b/openstack_dashboard/openstack/common/rpc/service.py
deleted file mode 100644
index b77f2a60..00000000
--- a/openstack_dashboard/openstack/common/rpc/service.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-# Copyright 2011 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common import rpc
-from openstack_dashboard.openstack.common.rpc import dispatcher as rpc_dispatcher
-from openstack_dashboard.openstack.common import service
-
-
-LOG = logging.getLogger(__name__)
-
-
-class Service(service.Service):
- """Service object for binaries running on hosts.
-
- A service enables rpc by listening to queues based on topic and host.
- """
- def __init__(self, host, topic, manager=None):
- super(Service, self).__init__()
- self.host = host
- self.topic = topic
- if manager is None:
- self.manager = self
- else:
- self.manager = manager
-
- def start(self):
- super(Service, self).start()
-
- self.conn = rpc.create_connection(new=True)
- LOG.debug(_("Creating Consumer connection for Service %s") %
- self.topic)
-
- dispatcher = rpc_dispatcher.RpcDispatcher([self.manager])
-
- # Share this same connection for these Consumers
- self.conn.create_consumer(self.topic, dispatcher, fanout=False)
-
- node_topic = '%s.%s' % (self.topic, self.host)
- self.conn.create_consumer(node_topic, dispatcher, fanout=False)
-
- self.conn.create_consumer(self.topic, dispatcher, fanout=True)
-
- # Hook to allow the manager to do other initializations after
- # the rpc connection is created.
- if callable(getattr(self.manager, 'initialize_service_hook', None)):
- self.manager.initialize_service_hook(self)
-
- # Consume from all consumers in a thread
- self.conn.consume_in_thread()
-
- def stop(self):
- # Try to shut the connection down, but if we get any sort of
- # errors, go ahead and ignore them.. as we're shutting down anyway
- try:
- self.conn.close()
- except Exception:
- pass
- super(Service, self).stop()
diff --git a/openstack_dashboard/openstack/common/rpc/zmq_receiver.py b/openstack_dashboard/openstack/common/rpc/zmq_receiver.py
deleted file mode 100755
index 63634168..00000000
--- a/openstack_dashboard/openstack/common/rpc/zmq_receiver.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 OpenStack Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import eventlet
-eventlet.monkey_patch()
-
-import contextlib
-import sys
-
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common import rpc
-from openstack_dashboard.openstack.common.rpc import impl_zmq
-
-CONF = cfg.CONF
-CONF.register_opts(rpc.rpc_opts)
-CONF.register_opts(impl_zmq.zmq_opts)
-
-
-def main():
- CONF(sys.argv[1:], project='oslo')
- logging.setup("oslo")
-
- with contextlib.closing(impl_zmq.ZmqProxy(CONF)) as reactor:
- reactor.consume_in_thread()
- reactor.wait()
diff --git a/openstack_dashboard/openstack/common/service.py b/openstack_dashboard/openstack/common/service.py
deleted file mode 100644
index f2343328..00000000
--- a/openstack_dashboard/openstack/common/service.py
+++ /dev/null
@@ -1,333 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# Copyright 2011 Justin Santa Barbara
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""Generic Node base class for all workers that run on hosts."""
-
-import errno
-import os
-import random
-import signal
-import sys
-import time
-
-import eventlet
-import logging as std_logging
-from oslo.config import cfg
-
-from openstack_dashboard.openstack.common import eventlet_backdoor
-from openstack_dashboard.openstack.common.gettextutils import _
-from openstack_dashboard.openstack.common import importutils
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common import threadgroup
-
-
-rpc = importutils.try_import('openstack_dashboard.openstack.common.rpc')
-CONF = cfg.CONF
-LOG = logging.getLogger(__name__)
-
-
-class Launcher(object):
- """Launch one or more services and wait for them to complete."""
-
- def __init__(self):
- """Initialize the service launcher.
-
- :returns: None
-
- """
- self._services = threadgroup.ThreadGroup()
- self.backdoor_port = eventlet_backdoor.initialize_if_enabled()
-
- @staticmethod
- def run_service(service):
- """Start and wait for a service to finish.
-
- :param service: service to run and wait for.
- :returns: None
-
- """
- service.start()
- service.wait()
-
- def launch_service(self, service):
- """Load and start the given service.
-
- :param service: The service you would like to start.
- :returns: None
-
- """
- service.backdoor_port = self.backdoor_port
- self._services.add_thread(self.run_service, service)
-
- def stop(self):
- """Stop all services which are currently running.
-
- :returns: None
-
- """
- self._services.stop()
-
- def wait(self):
- """Waits until all services have been stopped, and then returns.
-
- :returns: None
-
- """
- self._services.wait()
-
-
-class SignalExit(SystemExit):
- def __init__(self, signo, exccode=1):
- super(SignalExit, self).__init__(exccode)
- self.signo = signo
-
-
-class ServiceLauncher(Launcher):
- def _handle_signal(self, signo, frame):
- # Allow the process to be killed again and die from natural causes
- signal.signal(signal.SIGTERM, signal.SIG_DFL)
- signal.signal(signal.SIGINT, signal.SIG_DFL)
-
- raise SignalExit(signo)
-
- def wait(self):
- signal.signal(signal.SIGTERM, self._handle_signal)
- signal.signal(signal.SIGINT, self._handle_signal)
-
- LOG.debug(_('Full set of CONF:'))
- CONF.log_opt_values(LOG, std_logging.DEBUG)
-
- status = None
- try:
- super(ServiceLauncher, self).wait()
- except SignalExit as exc:
- signame = {signal.SIGTERM: 'SIGTERM',
- signal.SIGINT: 'SIGINT'}[exc.signo]
- LOG.info(_('Caught %s, exiting'), signame)
- status = exc.code
- except SystemExit as exc:
- status = exc.code
- finally:
- if rpc:
- rpc.cleanup()
- self.stop()
- return status
-
-
-class ServiceWrapper(object):
- def __init__(self, service, workers):
- self.service = service
- self.workers = workers
- self.children = set()
- self.forktimes = []
-
-
-class ProcessLauncher(object):
- def __init__(self):
- self.children = {}
- self.sigcaught = None
- self.running = True
- rfd, self.writepipe = os.pipe()
- self.readpipe = eventlet.greenio.GreenPipe(rfd, 'r')
-
- signal.signal(signal.SIGTERM, self._handle_signal)
- signal.signal(signal.SIGINT, self._handle_signal)
-
- def _handle_signal(self, signo, frame):
- self.sigcaught = signo
- self.running = False
-
- # Allow the process to be killed again and die from natural causes
- signal.signal(signal.SIGTERM, signal.SIG_DFL)
- signal.signal(signal.SIGINT, signal.SIG_DFL)
-
- def _pipe_watcher(self):
- # This will block until the write end is closed when the parent
- # dies unexpectedly
- self.readpipe.read()
-
- LOG.info(_('Parent process has died unexpectedly, exiting'))
-
- sys.exit(1)
-
- def _child_process(self, service):
- # Setup child signal handlers differently
- def _sigterm(*args):
- signal.signal(signal.SIGTERM, signal.SIG_DFL)
- raise SignalExit(signal.SIGTERM)
-
- signal.signal(signal.SIGTERM, _sigterm)
- # Block SIGINT and let the parent send us a SIGTERM
- signal.signal(signal.SIGINT, signal.SIG_IGN)
-
- # Reopen the eventlet hub to make sure we don't share an epoll
- # fd with parent and/or siblings, which would be bad
- eventlet.hubs.use_hub()
-
- # Close write to ensure only parent has it open
- os.close(self.writepipe)
- # Create greenthread to watch for parent to close pipe
- eventlet.spawn_n(self._pipe_watcher)
-
- # Reseed random number generator
- random.seed()
-
- launcher = Launcher()
- launcher.run_service(service)
-
- def _start_child(self, wrap):
- if len(wrap.forktimes) > wrap.workers:
- # Limit ourselves to one process a second (over the period of
- # number of workers * 1 second). This will allow workers to
- # start up quickly but ensure we don't fork off children that
- # die instantly too quickly.
- if time.time() - wrap.forktimes[0] < wrap.workers:
- LOG.info(_('Forking too fast, sleeping'))
- time.sleep(1)
-
- wrap.forktimes.pop(0)
-
- wrap.forktimes.append(time.time())
-
- pid = os.fork()
- if pid == 0:
- # NOTE(johannes): All exceptions are caught to ensure this
- # doesn't fallback into the loop spawning children. It would
- # be bad for a child to spawn more children.
- status = 0
- try:
- self._child_process(wrap.service)
- except SignalExit as exc:
- signame = {signal.SIGTERM: 'SIGTERM',
- signal.SIGINT: 'SIGINT'}[exc.signo]
- LOG.info(_('Caught %s, exiting'), signame)
- status = exc.code
- except SystemExit as exc:
- status = exc.code
- except BaseException:
- LOG.exception(_('Unhandled exception'))
- status = 2
- finally:
- wrap.service.stop()
-
- os._exit(status)
-
- LOG.info(_('Started child %d'), pid)
-
- wrap.children.add(pid)
- self.children[pid] = wrap
-
- return pid
-
- def launch_service(self, service, workers=1):
- wrap = ServiceWrapper(service, workers)
-
- LOG.info(_('Starting %d workers'), wrap.workers)
- while self.running and len(wrap.children) < wrap.workers:
- self._start_child(wrap)
-
- def _wait_child(self):
- try:
- # Don't block if no child processes have exited
- pid, status = os.waitpid(0, os.WNOHANG)
- if not pid:
- return None
- except OSError as exc:
- if exc.errno not in (errno.EINTR, errno.ECHILD):
- raise
- return None
-
- if os.WIFSIGNALED(status):
- sig = os.WTERMSIG(status)
- LOG.info(_('Child %(pid)d killed by signal %(sig)d'),
- dict(pid=pid, sig=sig))
- else:
- code = os.WEXITSTATUS(status)
- LOG.info(_('Child %(pid)s exited with status %(code)d'),
- dict(pid=pid, code=code))
-
- if pid not in self.children:
- LOG.warning(_('pid %d not in child list'), pid)
- return None
-
- wrap = self.children.pop(pid)
- wrap.children.remove(pid)
- return wrap
-
- def wait(self):
- """Loop waiting on children to die and respawning as necessary."""
-
- LOG.debug(_('Full set of CONF:'))
- CONF.log_opt_values(LOG, std_logging.DEBUG)
-
- while self.running:
- wrap = self._wait_child()
- if not wrap:
- # Yield to other threads if no children have exited
- # Sleep for a short time to avoid excessive CPU usage
- # (see bug #1095346)
- eventlet.greenthread.sleep(.01)
- continue
-
- while self.running and len(wrap.children) < wrap.workers:
- self._start_child(wrap)
-
- if self.sigcaught:
- signame = {signal.SIGTERM: 'SIGTERM',
- signal.SIGINT: 'SIGINT'}[self.sigcaught]
- LOG.info(_('Caught %s, stopping children'), signame)
-
- for pid in self.children:
- try:
- os.kill(pid, signal.SIGTERM)
- except OSError as exc:
- if exc.errno != errno.ESRCH:
- raise
-
- # Wait for children to die
- if self.children:
- LOG.info(_('Waiting on %d children to exit'), len(self.children))
- while self.children:
- self._wait_child()
-
-
-class Service(object):
- """Service object for binaries running on hosts."""
-
- def __init__(self, threads=1000):
- self.tg = threadgroup.ThreadGroup(threads)
-
- def start(self):
- pass
-
- def stop(self):
- self.tg.stop()
-
- def wait(self):
- self.tg.wait()
-
-
-def launch(service, workers=None):
- if workers:
- launcher = ProcessLauncher()
- launcher.launch_service(service, workers=workers)
- else:
- launcher = ServiceLauncher()
- launcher.launch_service(service)
- return launcher
diff --git a/openstack_dashboard/openstack/common/threadgroup.py b/openstack_dashboard/openstack/common/threadgroup.py
deleted file mode 100644
index 60981434..00000000
--- a/openstack_dashboard/openstack/common/threadgroup.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from eventlet import greenlet
-from eventlet import greenpool
-from eventlet import greenthread
-
-from openstack_dashboard.openstack.common import log as logging
-from openstack_dashboard.openstack.common import loopingcall
-
-
-LOG = logging.getLogger(__name__)
-
-
-def _thread_done(gt, *args, **kwargs):
- """Callback function to be passed to GreenThread.link() when we spawn()
- Calls the :class:`ThreadGroup` to notify if.
-
- """
- kwargs['group'].thread_done(kwargs['thread'])
-
-
-class Thread(object):
- """Wrapper around a greenthread, that holds a reference to the
- :class:`ThreadGroup`. The Thread will notify the :class:`ThreadGroup` when
- it has done so it can be removed from the threads list.
- """
- def __init__(self, thread, group):
- self.thread = thread
- self.thread.link(_thread_done, group=group, thread=self)
-
- def stop(self):
- self.thread.kill()
-
- def wait(self):
- return self.thread.wait()
-
-
-class ThreadGroup(object):
- """The point of the ThreadGroup classis to:
-
- * keep track of timers and greenthreads (making it easier to stop them
- when need be).
- * provide an easy API to add timers.
- """
- def __init__(self, thread_pool_size=10):
- self.pool = greenpool.GreenPool(thread_pool_size)
- self.threads = []
- self.timers = []
-
- def add_dynamic_timer(self, callback, initial_delay=None,
- periodic_interval_max=None, *args, **kwargs):
- timer = loopingcall.DynamicLoopingCall(callback, *args, **kwargs)
- timer.start(initial_delay=initial_delay,
- periodic_interval_max=periodic_interval_max)
- self.timers.append(timer)
-
- def add_timer(self, interval, callback, initial_delay=None,
- *args, **kwargs):
- pulse = loopingcall.FixedIntervalLoopingCall(callback, *args, **kwargs)
- pulse.start(interval=interval,
- initial_delay=initial_delay)
- self.timers.append(pulse)
-
- def add_thread(self, callback, *args, **kwargs):
- gt = self.pool.spawn(callback, *args, **kwargs)
- th = Thread(gt, self)
- self.threads.append(th)
-
- def thread_done(self, thread):
- self.threads.remove(thread)
-
- def stop(self):
- current = greenthread.getcurrent()
- for x in self.threads:
- if x is current:
- # don't kill the current thread.
- continue
- try:
- x.stop()
- except Exception as ex:
- LOG.exception(ex)
-
- for x in self.timers:
- try:
- x.stop()
- except Exception as ex:
- LOG.exception(ex)
- self.timers = []
-
- def wait(self):
- for x in self.timers:
- try:
- x.wait()
- except greenlet.GreenletExit:
- pass
- except Exception as ex:
- LOG.exception(ex)
- current = greenthread.getcurrent()
- for x in self.threads:
- if x is current:
- continue
- try:
- x.wait()
- except greenlet.GreenletExit:
- pass
- except Exception as ex:
- LOG.exception(ex)
diff --git a/openstack_dashboard/openstack/common/timeutils.py b/openstack_dashboard/openstack/common/timeutils.py
deleted file mode 100644
index 008e9c81..00000000
--- a/openstack_dashboard/openstack/common/timeutils.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2011 OpenStack Foundation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Time related utilities and helper functions.
-"""
-
-import calendar
-import datetime
-
-import iso8601
-
-
-# ISO 8601 extended time format with microseconds
-_ISO8601_TIME_FORMAT_SUBSECOND = '%Y-%m-%dT%H:%M:%S.%f'
-_ISO8601_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
-PERFECT_TIME_FORMAT = _ISO8601_TIME_FORMAT_SUBSECOND
-
-
-def isotime(at=None, subsecond=False):
- """Stringify time in ISO 8601 format."""
- if not at:
- at = utcnow()
- st = at.strftime(_ISO8601_TIME_FORMAT
- if not subsecond
- else _ISO8601_TIME_FORMAT_SUBSECOND)
- tz = at.tzinfo.tzname(None) if at.tzinfo else 'UTC'
- st += ('Z' if tz == 'UTC' else tz)
- return st
-
-
-def parse_isotime(timestr):
- """Parse time from ISO 8601 format."""
- try:
- return iso8601.parse_date(timestr)
- except iso8601.ParseError as e:
- raise ValueError(e.message)
- except TypeError as e:
- raise ValueError(e.message)
-
-
-def strtime(at=None, fmt=PERFECT_TIME_FORMAT):
- """Returns formatted utcnow."""
- if not at:
- at = utcnow()
- return at.strftime(fmt)
-
-
-def parse_strtime(timestr, fmt=PERFECT_TIME_FORMAT):
- """Turn a formatted time back into a datetime."""
- return datetime.datetime.strptime(timestr, fmt)
-
-
-def normalize_time(timestamp):
- """Normalize time in arbitrary timezone to UTC naive object."""
- offset = timestamp.utcoffset()
- if offset is None:
- return timestamp
- return timestamp.replace(tzinfo=None) - offset
-
-
-def is_older_than(before, seconds):
- """Return True if before is older than seconds."""
- if isinstance(before, basestring):
- before = parse_strtime(before).replace(tzinfo=None)
- return utcnow() - before > datetime.timedelta(seconds=seconds)
-
-
-def is_newer_than(after, seconds):
- """Return True if after is newer than seconds."""
- if isinstance(after, basestring):
- after = parse_strtime(after).replace(tzinfo=None)
- return after - utcnow() > datetime.timedelta(seconds=seconds)
-
-
-def utcnow_ts():
- """Timestamp version of our utcnow function."""
- return calendar.timegm(utcnow().timetuple())
-
-
-def utcnow():
- """Overridable version of utils.utcnow."""
- if utcnow.override_time:
- try:
- return utcnow.override_time.pop(0)
- except AttributeError:
- return utcnow.override_time
- return datetime.datetime.utcnow()
-
-
-def iso8601_from_timestamp(timestamp):
- """Returns a iso8601 formated date from timestamp."""
- return isotime(datetime.datetime.utcfromtimestamp(timestamp))
-
-
-utcnow.override_time = None
-
-
-def set_time_override(override_time=datetime.datetime.utcnow()):
- """
- Override utils.utcnow to return a constant time or a list thereof,
- one at a time.
- """
- utcnow.override_time = override_time
-
-
-def advance_time_delta(timedelta):
- """Advance overridden time using a datetime.timedelta."""
- assert(not utcnow.override_time is None)
- try:
- for dt in utcnow.override_time:
- dt += timedelta
- except TypeError:
- utcnow.override_time += timedelta
-
-
-def advance_time_seconds(seconds):
- """Advance overridden time by seconds."""
- advance_time_delta(datetime.timedelta(0, seconds))
-
-
-def clear_time_override():
- """Remove the overridden time."""
- utcnow.override_time = None
-
-
-def marshall_now(now=None):
- """Make an rpc-safe datetime with microseconds.
-
- Note: tzinfo is stripped, but not required for relative times.
- """
- if not now:
- now = utcnow()
- return dict(day=now.day, month=now.month, year=now.year, hour=now.hour,
- minute=now.minute, second=now.second,
- microsecond=now.microsecond)
-
-
-def unmarshall_time(tyme):
- """Unmarshall a datetime dict."""
- return datetime.datetime(day=tyme['day'],
- month=tyme['month'],
- year=tyme['year'],
- hour=tyme['hour'],
- minute=tyme['minute'],
- second=tyme['second'],
- microsecond=tyme['microsecond'])
-
-
-def delta_seconds(before, after):
- """
- Compute the difference in seconds between two date, time, or
- datetime objects (as a float, to microsecond resolution).
- """
- delta = after - before
- try:
- return delta.total_seconds()
- except AttributeError:
- return ((delta.days * 24 * 3600) + delta.seconds +
- float(delta.microseconds) / (10 ** 6))
-
-
-def is_soon(dt, window):
- """
- Determines if time is going to happen in the next window seconds.
-
- :params dt: the time
- :params window: minimum seconds to remain to consider the time not soon
-
- :return: True if expiration is within the given duration
- """
- soon = (utcnow() + datetime.timedelta(seconds=window))
- return normalize_time(dt) <= soon
diff --git a/openstack_dashboard/openstack/common/uuidutils.py b/openstack_dashboard/openstack/common/uuidutils.py
deleted file mode 100644
index 7608acb9..00000000
--- a/openstack_dashboard/openstack/common/uuidutils.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 Intel Corporation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-UUID related utilities and helper functions.
-"""
-
-import uuid
-
-
-def generate_uuid():
- return str(uuid.uuid4())
-
-
-def is_uuid_like(val):
- """Returns validation of a value as a UUID.
-
- For our purposes, a UUID is a canonical form string:
- aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
-
- """
- try:
- return str(uuid.UUID(val)) == val
- except (TypeError, ValueError, AttributeError):
- return False
diff --git a/openstack_dashboard/settings.py b/openstack_dashboard/settings.py
deleted file mode 100644
index e7fb4a5a..00000000
--- a/openstack_dashboard/settings.py
+++ /dev/null
@@ -1,207 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-import os
-import sys
-import warnings
-
-from openstack_dashboard import exceptions
-
-warnings.formatwarning = lambda message, category, *args, **kwargs: \
- '%s: %s' % (category.__name__, message)
-
-ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
-BIN_DIR = os.path.abspath(os.path.join(ROOT_PATH, '..', 'bin'))
-
-if ROOT_PATH not in sys.path:
- sys.path.append(ROOT_PATH)
-
-DEBUG = False
-TEMPLATE_DEBUG = DEBUG
-
-SITE_BRANDING = 'OpenStack Dashboard'
-
-LOGIN_URL = '/auth/login/'
-LOGOUT_URL = '/auth/logout/'
-# LOGIN_REDIRECT_URL can be used as an alternative for
-# HORIZON_CONFIG.user_home, if user_home is not set.
-# Do not set it to '/home/', as this will cause circular redirect loop
-LOGIN_REDIRECT_URL = '/'
-
-MEDIA_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '..', 'media'))
-MEDIA_URL = '/media/'
-STATIC_ROOT = os.path.abspath(os.path.join(ROOT_PATH, '..', 'static'))
-STATIC_URL = '/static/'
-
-ROOT_URLCONF = 'openstack_dashboard.urls'
-
-HORIZON_CONFIG = {
- 'dashboards': ('project', 'admin', 'infrastructure', 'settings',),
- 'default_dashboard': 'project',
- 'user_home': 'openstack_dashboard.views.get_user_home',
- 'ajax_queue_limit': 10,
- 'auto_fade_alerts': {
- 'delay': 3000,
- 'fade_duration': 1500,
- 'types': ['alert-success', 'alert-info']
- },
- 'help_url': "http://docs.openstack.org",
- 'exceptions': {'recoverable': exceptions.RECOVERABLE,
- 'not_found': exceptions.NOT_FOUND,
- 'unauthorized': exceptions.UNAUTHORIZED},
-}
-
-# Set to True to allow users to upload images to glance via Horizon server.
-# When enabled, a file form field will appear on the create image form.
-# See documentation for deployment considerations.
-HORIZON_IMAGES_ALLOW_UPLOAD = True
-
-MIDDLEWARE_CLASSES = (
- 'django.middleware.common.CommonMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',
- 'horizon.middleware.HorizonMiddleware',
- 'django.middleware.doc.XViewMiddleware',
- 'django.middleware.locale.LocaleMiddleware',
- 'django.middleware.clickjacking.XFrameOptionsMiddleware',
-)
-
-TEMPLATE_CONTEXT_PROCESSORS = (
- 'django.core.context_processors.debug',
- 'django.core.context_processors.i18n',
- 'django.core.context_processors.request',
- 'django.core.context_processors.media',
- 'django.core.context_processors.static',
- 'django.contrib.messages.context_processors.messages',
- 'horizon.context_processors.horizon',
- 'openstack_dashboard.context_processors.openstack',
-)
-
-TEMPLATE_LOADERS = (
- 'django.template.loaders.filesystem.Loader',
- 'django.template.loaders.app_directories.Loader',
- 'horizon.loaders.TemplateLoader'
-)
-
-TEMPLATE_DIRS = (
- os.path.join(ROOT_PATH, 'templates'),
-)
-
-STATICFILES_FINDERS = (
- 'compressor.finders.CompressorFinder',
- 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
-)
-
-less_binary = os.path.join(BIN_DIR, 'less', 'lessc')
-COMPRESS_PRECOMPILERS = (
- ('text/less', (less_binary + ' {infile} {outfile}')),
-)
-
-COMPRESS_CSS_FILTERS = (
- 'compressor.filters.css_default.CssAbsoluteFilter',
-)
-
-COMPRESS_ENABLED = True
-COMPRESS_OUTPUT_DIR = 'dashboard'
-COMPRESS_CSS_HASHING_METHOD = 'hash'
-COMPRESS_PARSER = 'compressor.parser.HtmlParser'
-
-INSTALLED_APPS = (
- 'openstack_dashboard',
- 'django.contrib.contenttypes',
- 'django.contrib.auth',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
- 'django.contrib.humanize',
- 'compressor',
- 'horizon',
- 'openstack_dashboard.dashboards.project',
- 'openstack_dashboard.dashboards.admin',
- 'openstack_dashboard.dashboards.infrastructure',
- 'openstack_dashboard.dashboards.settings',
- 'openstack_auth',
-)
-
-TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
-AUTHENTICATION_BACKENDS = ('openstack_auth.backend.KeystoneBackend',)
-MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
-
-SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
-SESSION_COOKIE_HTTPONLY = True
-SESSION_EXPIRE_AT_BROWSER_CLOSE = True
-SESSION_COOKIE_SECURE = False
-SESSION_TIMEOUT = 1800
-
-gettext_noop = lambda s: s
-LANGUAGES = (
- ('bg', gettext_noop('Bulgarian (Bulgaria)')),
- ('cs', gettext_noop('Czech')),
- ('en', gettext_noop('English')),
- ('es', gettext_noop('Spanish')),
- ('fr', gettext_noop('French')),
- ('it', gettext_noop('Italiano')),
- ('ja', gettext_noop('Japanese')),
- ('ko', gettext_noop('Korean (Korea)')),
- ('nl', gettext_noop('Dutch (Netherlands)')),
- ('pl', gettext_noop('Polish')),
- ('pt', gettext_noop('Portuguese')),
- ('pt-br', gettext_noop('Portuguese (Brazil)')),
- ('zh-cn', gettext_noop('Simplified Chinese')),
- ('zh-tw', gettext_noop('Traditional Chinese')),
-)
-LANGUAGE_CODE = 'en'
-USE_I18N = True
-USE_L10N = True
-USE_TZ = True
-
-OPENSTACK_KEYSTONE_DEFAULT_ROLE = 'Member'
-
-DEFAULT_EXCEPTION_REPORTER_FILTER = 'horizon.exceptions.HorizonReporterFilter'
-
-try:
- from local.local_settings import * # noqa
-except ImportError:
- logging.warning("No local_settings file found.")
-
-# Add HORIZON_CONFIG to the context information for offline compression
-COMPRESS_OFFLINE_CONTEXT = {
- 'STATIC_URL': STATIC_URL,
- 'HORIZON_CONFIG': HORIZON_CONFIG
-}
-
-if DEBUG:
- logging.basicConfig(level=logging.DEBUG)
-
-# FIXME: configuration for dummy data
-DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': 'openstack_dashboard/dummydb.sqlite',
- }
-}
-
-# FIXME: configuration for dummy data
-FIXTURE_DIRS = (
- 'openstack_dashboard/dashboards/infrastructure/fixtures/',
-)
diff --git a/openstack_dashboard/static/bootstrap/img/glyphicons-halflings-white.png b/openstack_dashboard/static/bootstrap/img/glyphicons-halflings-white.png
deleted file mode 100644
index a20760bf..00000000
--- a/openstack_dashboard/static/bootstrap/img/glyphicons-halflings-white.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/bootstrap/img/glyphicons-halflings.png b/openstack_dashboard/static/bootstrap/img/glyphicons-halflings.png
deleted file mode 100644
index 92d4445d..00000000
--- a/openstack_dashboard/static/bootstrap/img/glyphicons-halflings.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/bootstrap/less/accordion.less b/openstack_dashboard/static/bootstrap/less/accordion.less
deleted file mode 100644
index 11a36b54..00000000
--- a/openstack_dashboard/static/bootstrap/less/accordion.less
+++ /dev/null
@@ -1,28 +0,0 @@
-// ACCORDION
-// ---------
-
-
-// Parent container
-.accordion {
- margin-bottom: @baseLineHeight;
-}
-
-// Group == heading + body
-.accordion-group {
- margin-bottom: 2px;
- border: 1px solid #e5e5e5;
- .border-radius(4px);
-}
-.accordion-heading {
- border-bottom: 0;
-}
-.accordion-heading .accordion-toggle {
- display: block;
- padding: 8px 15px;
-}
-
-// Inner needs the styles because you can't animate properly with any styles on the element
-.accordion-inner {
- padding: 9px 15px;
- border-top: 1px solid #e5e5e5;
-}
diff --git a/openstack_dashboard/static/bootstrap/less/alerts.less b/openstack_dashboard/static/bootstrap/less/alerts.less
deleted file mode 100644
index 562826fd..00000000
--- a/openstack_dashboard/static/bootstrap/less/alerts.less
+++ /dev/null
@@ -1,70 +0,0 @@
-// ALERT STYLES
-// ------------
-
-// Base alert styles
-.alert {
- padding: 8px 35px 8px 14px;
- margin-bottom: @baseLineHeight;
- text-shadow: 0 1px 0 rgba(255,255,255,.5);
- background-color: @warningBackground;
- border: 1px solid @warningBorder;
- .border-radius(4px);
-}
-.alert,
-.alert-heading {
- color: @warningText;
-}
-
-// Adjust close link position
-.alert .close {
- position: relative;
- top: -2px;
- right: -21px;
- line-height: 18px;
-}
-
-// Alternate styles
-// ----------------
-
-.alert-success {
- background-color: @successBackground;
- border-color: @successBorder;
-}
-.alert-success,
-.alert-success .alert-heading {
- color: @successText;
-}
-.alert-danger,
-.alert-error {
- background-color: @errorBackground;
- border-color: @errorBorder;
-}
-.alert-danger,
-.alert-error,
-.alert-danger .alert-heading,
-.alert-error .alert-heading {
- color: @errorText;
-}
-.alert-info {
- background-color: @infoBackground;
- border-color: @infoBorder;
-}
-.alert-info,
-.alert-info .alert-heading {
- color: @infoText;
-}
-
-
-// Block alerts
-// ------------------------
-.alert-block {
- padding-top: 14px;
- padding-bottom: 14px;
-}
-.alert-block > p,
-.alert-block > ul {
- margin-bottom: 0;
-}
-.alert-block p + p {
- margin-top: 5px;
-}
diff --git a/openstack_dashboard/static/bootstrap/less/bootstrap.less b/openstack_dashboard/static/bootstrap/less/bootstrap.less
deleted file mode 100644
index 4b09b7aa..00000000
--- a/openstack_dashboard/static/bootstrap/less/bootstrap.less
+++ /dev/null
@@ -1,62 +0,0 @@
-/*!
- * Bootstrap v2.0.1
- *
- * Copyright 2012 Twitter, Inc
- * Licensed under the Apache License v2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Designed and built with all the love in the world @twitter by @mdo and @fat.
- */
-
-// CSS Reset
-@import "reset.less";
-
-// Core variables and mixins
-@import "variables.less"; // Modify this for custom colors, font-sizes, etc
-@import "mixins.less";
-
-// Grid system and page structure
-@import "scaffolding.less";
-@import "grid.less";
-@import "layouts.less";
-
-// Base CSS
-@import "type.less";
-@import "code.less";
-@import "forms.less";
-@import "tables.less";
-
-// Components: common
-@import "sprites.less";
-@import "dropdowns.less";
-@import "wells.less";
-@import "component-animations.less";
-@import "close.less";
-
-// Components: Buttons & Alerts
-@import "buttons.less";
-@import "button-groups.less";
-@import "alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less
-
-// Components: Nav
-@import "navs.less";
-@import "navbar.less";
-@import "breadcrumbs.less";
-@import "pagination.less";
-@import "pager.less";
-
-// Components: Popovers
-@import "modals.less";
-@import "tooltip.less";
-@import "popovers.less";
-
-// Components: Misc
-@import "thumbnails.less";
-@import "labels.less";
-@import "progress-bars.less";
-@import "accordion.less";
-@import "carousel.less";
-@import "hero-unit.less";
-
-// Utility classes
-@import "utilities.less"; // Has to be last to override when necessary
diff --git a/openstack_dashboard/static/bootstrap/less/breadcrumbs.less b/openstack_dashboard/static/bootstrap/less/breadcrumbs.less
deleted file mode 100644
index 39060bad..00000000
--- a/openstack_dashboard/static/bootstrap/less/breadcrumbs.less
+++ /dev/null
@@ -1,22 +0,0 @@
-// BREADCRUMBS
-// -----------
-
-.breadcrumb {
- padding: 7px 14px;
- margin: 0 0 @baseLineHeight;
- #gradient > .vertical(@white, #f5f5f5);
- border: 1px solid #ddd;
- .border-radius(3px);
- .box-shadow(inset 0 1px 0 @white);
- li {
- display: inline-block;
- text-shadow: 0 1px 0 @white;
- }
- .divider {
- padding: 0 5px;
- color: @grayLight;
- }
- .active a {
- color: @grayDark;
- }
-}
diff --git a/openstack_dashboard/static/bootstrap/less/button-groups.less b/openstack_dashboard/static/bootstrap/less/button-groups.less
deleted file mode 100644
index a04220a9..00000000
--- a/openstack_dashboard/static/bootstrap/less/button-groups.less
+++ /dev/null
@@ -1,148 +0,0 @@
-// BUTTON GROUPS
-// -------------
-
-
-// Make the div behave like a button
-.btn-group {
- position: relative;
- .clearfix(); // clears the floated buttons
- .ie7-restore-left-whitespace();
-}
-
-// Space out series of button groups
-.btn-group + .btn-group {
- margin-left: 5px;
-}
-
-// Optional: Group multiple button groups together for a toolbar
-.btn-toolbar {
- margin-top: @baseLineHeight / 2;
- margin-bottom: @baseLineHeight / 2;
- .btn-group {
- display: inline-block;
- .ie7-inline-block();
- }
-}
-
-// Float them, remove border radius, then re-add to first and last elements
-.btn-group .btn {
- position: relative;
- float: left;
- margin-left: -1px;
- .border-radius(0);
-}
-// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match
-.btn-group .btn:first-child {
- margin-left: 0;
- -webkit-border-top-left-radius: 4px;
- -moz-border-radius-topleft: 4px;
- border-top-left-radius: 4px;
- -webkit-border-bottom-left-radius: 4px;
- -moz-border-radius-bottomleft: 4px;
- border-bottom-left-radius: 4px;
-}
-.btn-group .btn:last-child,
-.btn-group .dropdown-toggle {
- -webkit-border-top-right-radius: 4px;
- -moz-border-radius-topright: 4px;
- border-top-right-radius: 4px;
- -webkit-border-bottom-right-radius: 4px;
- -moz-border-radius-bottomright: 4px;
- border-bottom-right-radius: 4px;
-}
-// Reset corners for large buttons
-.btn-group .btn.large:first-child {
- margin-left: 0;
- -webkit-border-top-left-radius: 6px;
- -moz-border-radius-topleft: 6px;
- border-top-left-radius: 6px;
- -webkit-border-bottom-left-radius: 6px;
- -moz-border-radius-bottomleft: 6px;
- border-bottom-left-radius: 6px;
-}
-.btn-group .btn.large:last-child,
-.btn-group .large.dropdown-toggle {
- -webkit-border-top-right-radius: 6px;
- -moz-border-radius-topright: 6px;
- border-top-right-radius: 6px;
- -webkit-border-bottom-right-radius: 6px;
- -moz-border-radius-bottomright: 6px;
- border-bottom-right-radius: 6px;
-}
-
-// On hover/focus/active, bring the proper btn to front
-.btn-group .btn:hover,
-.btn-group .btn:focus,
-.btn-group .btn:active,
-.btn-group .btn.active {
- z-index: 2;
-}
-
-// On active and open, don't show outline
-.btn-group .dropdown-toggle:active,
-.btn-group.open .dropdown-toggle {
- outline: 0;
-}
-
-
-
-// Split button dropdowns
-// ----------------------
-
-// Give the line between buttons some depth
-.btn-group .dropdown-toggle {
- padding-left: 8px;
- padding-right: 8px;
- @shadow: inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
- .box-shadow(@shadow);
- *padding-top: 5px;
- *padding-bottom: 5px;
-}
-
-.btn-group.open {
- // IE7's z-index only goes to the nearest positioned ancestor, which would
- // make the menu appear below buttons that appeared later on the page
- *z-index: @zindexDropdown;
-
- // Reposition menu on open and round all corners
- .dropdown-menu {
- display: block;
- margin-top: 1px;
- .border-radius(5px);
- }
-
- .dropdown-toggle {
- background-image: none;
- @shadow: inset 0 1px 6px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);
- .box-shadow(@shadow);
- }
-}
-
-// Reposition the caret
-.btn .caret {
- margin-top: 7px;
- margin-left: 0;
-}
-.btn:hover .caret,
-.open.btn-group .caret {
- .opacity(100);
-}
-
-
-// Account for other colors
-.btn-primary,
-.btn-danger,
-.btn-info,
-.btn-success,
-.btn-inverse {
- .caret {
- border-top-color: @white;
- .opacity(75);
- }
-}
-
-// Small button dropdowns
-.btn-small .caret {
- margin-top: 4px;
-}
-
diff --git a/openstack_dashboard/static/bootstrap/less/buttons.less b/openstack_dashboard/static/bootstrap/less/buttons.less
deleted file mode 100644
index 55e9fbf1..00000000
--- a/openstack_dashboard/static/bootstrap/less/buttons.less
+++ /dev/null
@@ -1,183 +0,0 @@
-// BUTTON STYLES
-// -------------
-
-
-// Base styles
-// --------------------------------------------------
-
-// Core
-.btn {
- display: inline-block;
- padding: 4px 10px 4px;
- margin-bottom: 0; // For input.btn
- font-size: @baseFontSize;
- line-height: @baseLineHeight;
- color: @grayDark;
- text-align: center;
- text-shadow: 0 1px 1px rgba(255,255,255,.75);
- vertical-align: middle;
- .buttonBackground(@white, darken(@white, 10%));
- border: 1px solid #ccc;
- border-bottom-color: #bbb;
- .border-radius(4px);
- @shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
- .box-shadow(@shadow);
- cursor: pointer;
-
- // Give IE7 some love
- .reset-filter();
- .ie7-restore-left-whitespace();
-}
-
-// Hover state
-.btn:hover {
- color: @grayDark;
- text-decoration: none;
- background-color: darken(@white, 10%);
- background-position: 0 -15px;
-
- // transition is only when going to hover, otherwise the background
- // behind the gradient (there for IE<=9 fallback) gets mismatched
- .transition(background-position .1s linear);
-}
-
-// Focus state for keyboard and accessibility
-.btn:focus {
- .tab-focus();
-}
-
-// Active state
-.btn.active,
-.btn:active {
- background-image: none;
- @shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);
- .box-shadow(@shadow);
- background-color: darken(@white, 10%);
- background-color: darken(@white, 15%) e("\9");
- outline: 0;
-}
-
-// Disabled state
-.btn.disabled,
-.btn[disabled] {
- cursor: default;
- background-image: none;
- background-color: darken(@white, 10%);
- .opacity(65);
- .box-shadow(none);
-}
-
-
-// Button Sizes
-// --------------------------------------------------
-
-// Large
-.btn-large {
- padding: 9px 14px;
- font-size: @baseFontSize + 2px;
- line-height: normal;
- .border-radius(5px);
-}
-.btn-large [class^="icon-"] {
- margin-top: 1px;
-}
-
-// Small
-.btn-small {
- padding: 5px 9px;
- font-size: @baseFontSize - 2px;
- line-height: @baseLineHeight - 2px;
-}
-.btn-small [class^="icon-"] {
- margin-top: -1px;
-}
-
-// Mini
-.btn-mini {
- padding: 2px 6px;
- font-size: @baseFontSize - 2px;
- line-height: @baseLineHeight - 4px;
-}
-
-
-// Alternate buttons
-// --------------------------------------------------
-
-// Set text color
-// -------------------------
-.btn-primary,
-.btn-primary:hover,
-.btn-warning,
-.btn-warning:hover,
-.btn-danger,
-.btn-danger:hover,
-.btn-success,
-.btn-success:hover,
-.btn-info,
-.btn-info:hover,
-.btn-inverse,
-.btn-inverse:hover {
- text-shadow: 0 -1px 0 rgba(0,0,0,.25);
- color: @white;
-}
-// Provide *some* extra contrast for those who can get it
-.btn-primary.active,
-.btn-warning.active,
-.btn-danger.active,
-.btn-success.active,
-.btn-info.active,
-.btn-dark.active {
- color: rgba(255,255,255,.75);
-}
-
-// Set the backgrounds
-// -------------------------
-.btn-primary {
- .buttonBackground(@primaryButtonBackground, spin(@primaryButtonBackground, 20));
-}
-// Warning appears are orange
-.btn-warning {
- .buttonBackground(lighten(@orange, 15%), @orange);
-}
-// Danger and error appear as red
-.btn-danger {
- .buttonBackground(#ee5f5b, #bd362f);
-}
-// Success appears as green
-.btn-success {
- .buttonBackground(#62c462, #51a351);
-}
-// Info appears as a neutral blue
-.btn-info {
- .buttonBackground(#5bc0de, #2f96b4);
-}
-// Inverse appears as dark gray
-.btn-inverse {
- .buttonBackground(#454545, #262626);
-}
-
-
-// Cross-browser Jank
-// --------------------------------------------------
-
-button.btn,
-input[type="submit"].btn {
-
- // Firefox 3.6 only I believe
- &::-moz-focus-inner {
- padding: 0;
- border: 0;
- }
-
- // IE7 has some default padding on button controls
- *padding-top: 2px;
- *padding-bottom: 2px;
- &.large {
- *padding-top: 7px;
- *padding-bottom: 7px;
- }
- &.small {
- *padding-top: 3px;
- *padding-bottom: 3px;
- }
-}
diff --git a/openstack_dashboard/static/bootstrap/less/carousel.less b/openstack_dashboard/static/bootstrap/less/carousel.less
deleted file mode 100644
index 8fbd3031..00000000
--- a/openstack_dashboard/static/bootstrap/less/carousel.less
+++ /dev/null
@@ -1,121 +0,0 @@
-// CAROUSEL
-// --------
-
-.carousel {
- position: relative;
- margin-bottom: @baseLineHeight;
- line-height: 1;
-}
-
-.carousel-inner {
- overflow: hidden;
- width: 100%;
- position: relative;
-}
-
-.carousel {
-
- .item {
- display: none;
- position: relative;
- .transition(.6s ease-in-out left);
- }
-
- // Account for jankitude on images
- .item > img {
- display: block;
- line-height: 1;
- }
-
- .active,
- .next,
- .prev { display: block; }
-
- .active {
- left: 0;
- }
-
- .next,
- .prev {
- position: absolute;
- top: 0;
- width: 100%;
- }
-
- .next {
- left: 100%;
- }
- .prev {
- left: -100%;
- }
- .next.left,
- .prev.right {
- left: 0;
- }
-
- .active.left {
- left: -100%;
- }
- .active.right {
- left: 100%;
- }
-
-}
-
-// Left/right controls for nav
-// ---------------------------
-
-.carousel-control {
- position: absolute;
- top: 40%;
- left: 15px;
- width: 40px;
- height: 40px;
- margin-top: -20px;
- font-size: 60px;
- font-weight: 100;
- line-height: 30px;
- color: @white;
- text-align: center;
- background: @grayDarker;
- border: 3px solid @white;
- .border-radius(23px);
- .opacity(50);
-
- // we can't have this transition here
- // because webkit cancels the carousel
- // animation if you trip this while
- // in the middle of another animation
- // ;_;
- // .transition(opacity .2s linear);
-
- // Reposition the right one
- &.right {
- left: auto;
- right: 15px;
- }
-
- // Hover state
- &:hover {
- color: @white;
- text-decoration: none;
- .opacity(90);
- }
-}
-
-// Caption for text below images
-// -----------------------------
-
-.carousel-caption {
- position: absolute;
- left: 0;
- right: 0;
- bottom: 0;
- padding: 10px 15px 5px;
- background: @grayDark;
- background: rgba(0,0,0,.75);
-}
-.carousel-caption h4,
-.carousel-caption p {
- color: @white;
-}
diff --git a/openstack_dashboard/static/bootstrap/less/close.less b/openstack_dashboard/static/bootstrap/less/close.less
deleted file mode 100644
index a0e5edba..00000000
--- a/openstack_dashboard/static/bootstrap/less/close.less
+++ /dev/null
@@ -1,18 +0,0 @@
-// CLOSE ICONS
-// -----------
-
-.close {
- float: right;
- font-size: 20px;
- font-weight: bold;
- line-height: @baseLineHeight;
- color: @black;
- text-shadow: 0 1px 0 rgba(255,255,255,1);
- .opacity(20);
- &:hover {
- color: @black;
- text-decoration: none;
- .opacity(40);
- cursor: pointer;
- }
-}
diff --git a/openstack_dashboard/static/bootstrap/less/code.less b/openstack_dashboard/static/bootstrap/less/code.less
deleted file mode 100644
index e2157d8a..00000000
--- a/openstack_dashboard/static/bootstrap/less/code.less
+++ /dev/null
@@ -1,57 +0,0 @@
-// Code.less
-// Code typography styles for the <code> and <pre> elements
-// --------------------------------------------------------
-
-// Inline and block code styles
-code,
-pre {
- padding: 0 3px 2px;
- #font > #family > .monospace;
- font-size: @baseFontSize - 1;
- color: @grayDark;
- .border-radius(3px);
-}
-
-// Inline code
-code {
- padding: 3px 4px;
- color: #d14;
- background-color: #f7f7f9;
- border: 1px solid #e1e1e8;
-}
-
-// Blocks of code
-pre {
- display: block;
- padding: (@baseLineHeight - 1) / 2;
- margin: 0 0 @baseLineHeight / 2;
- font-size: 12px;
- line-height: @baseLineHeight;
- background-color: #f5f5f5;
- border: 1px solid #ccc; // fallback for IE7-8
- border: 1px solid rgba(0,0,0,.15);
- .border-radius(4px);
- white-space: pre;
- white-space: pre-wrap;
- word-break: break-all;
- word-wrap: break-word;
-
- // Make prettyprint styles more spaced out for readability
- &.prettyprint {
- margin-bottom: @baseLineHeight;
- }
-
- // Account for some code outputs that place code tags in pre tags
- code {
- padding: 0;
- color: inherit;
- background-color: transparent;
- border: 0;
- }
-}
-
-// Enable scrollable blocks of code
-.pre-scrollable {
- max-height: 340px;
- overflow-y: scroll;
-} \ No newline at end of file
diff --git a/openstack_dashboard/static/bootstrap/less/component-animations.less b/openstack_dashboard/static/bootstrap/less/component-animations.less
deleted file mode 100644
index 4f2a4fd1..00000000
--- a/openstack_dashboard/static/bootstrap/less/component-animations.less
+++ /dev/null
@@ -1,18 +0,0 @@
-// COMPONENT ANIMATIONS
-// --------------------
-
-.fade {
- .transition(opacity .15s linear);
- opacity: 0;
- &.in {
- opacity: 1;
- }
-}
-
-.collapse {
- .transition(height .35s ease);
- position:relative;
- overflow:hidden;
- height: 0;
- &.in { height: auto; }
-}
diff --git a/openstack_dashboard/static/bootstrap/less/datepicker.less b/openstack_dashboard/static/bootstrap/less/datepicker.less
deleted file mode 100644
index 76967442..00000000
--- a/openstack_dashboard/static/bootstrap/less/datepicker.less
+++ /dev/null
@@ -1,183 +0,0 @@
-/*!
- * Datepicker for Bootstrap
- *
- * Copyright 2012 Stefan Petre
- * Licensed under the Apache License v2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- */
-
-.datepicker {
- top: 0;
- left: 0;
- padding: 4px;
- margin-top: 1px;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
- /*.dow {
- border-top: 1px solid #ddd !important;
- }*/
-
-}
-.datepicker:before {
- content: '';
- display: inline-block;
- border-left: 7px solid transparent;
- border-right: 7px solid transparent;
- border-bottom: 7px solid #ccc;
- border-bottom-color: rgba(0, 0, 0, 0.2);
- position: absolute;
- top: -7px;
- left: 6px;
-}
-.datepicker:after {
- content: '';
- display: inline-block;
- border-left: 6px solid transparent;
- border-right: 6px solid transparent;
- border-bottom: 6px solid #ffffff;
- position: absolute;
- top: -6px;
- left: 7px;
-}
-.datepicker > div {
- display: none;
-}
-.datepicker table {
- width: 100%;
- margin: 0;
-}
-.datepicker td,
-.datepicker th {
- text-align: center;
- width: 20px;
- height: 20px;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
-}
-.datepicker td.day:hover {
- background: #eeeeee;
- cursor: pointer;
-}
-.datepicker td.day.disabled {
- color: #eeeeee;
-}
-.datepicker td.old,
-.datepicker td.new {
- color: #999999;
-}
-.datepicker td.active,
-.datepicker td.active:hover {
- color: #ffffff;
- background-color: #006dcc;
- background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
- background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
- background-image: -o-linear-gradient(top, #0088cc, #0044cc);
- background-image: linear-gradient(to bottom, #0088cc, #0044cc);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
- border-color: #0044cc #0044cc #002a80;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- *background-color: #0044cc;
- /* Darken IE7 buttons by default so they stand out more given they won't have borders */
-
- filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
- color: #fff;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-}
-.datepicker td.active:hover,
-.datepicker td.active:hover:hover,
-.datepicker td.active:focus,
-.datepicker td.active:hover:focus,
-.datepicker td.active:active,
-.datepicker td.active:hover:active,
-.datepicker td.active.active,
-.datepicker td.active:hover.active,
-.datepicker td.active.disabled,
-.datepicker td.active:hover.disabled,
-.datepicker td.active[disabled],
-.datepicker td.active:hover[disabled] {
- color: #ffffff;
- background-color: #0044cc;
- *background-color: #003bb3;
-}
-.datepicker td.active:active,
-.datepicker td.active:hover:active,
-.datepicker td.active.active,
-.datepicker td.active:hover.active {
- background-color: #003399 \9;
-}
-.datepicker td span {
- display: block;
- width: 47px;
- height: 54px;
- line-height: 54px;
- float: left;
- margin: 2px;
- cursor: pointer;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
-}
-.datepicker td span:hover {
- background: #eeeeee;
-}
-.datepicker td span.active {
- color: #ffffff;
- background-color: #006dcc;
- background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
- background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
- background-image: -o-linear-gradient(top, #0088cc, #0044cc);
- background-image: linear-gradient(to bottom, #0088cc, #0044cc);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
- border-color: #0044cc #0044cc #002a80;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- *background-color: #0044cc;
- /* Darken IE7 buttons by default so they stand out more given they won't have borders */
-
- filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
- color: #fff;
- text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
-}
-.datepicker td span.active:hover,
-.datepicker td span.active:focus,
-.datepicker td span.active:active,
-.datepicker td span.active.active,
-.datepicker td span.active.disabled,
-.datepicker td span.active[disabled] {
- color: #ffffff;
- background-color: #0044cc;
- *background-color: #003bb3;
-}
-.datepicker td span.active:active,
-.datepicker td span.active.active {
- background-color: #003399 \9;
-}
-.datepicker td span.old {
- color: #999999;
-}
-.datepicker th.switch {
- width: 145px;
-}
-.datepicker th.next,
-.datepicker th.prev {
- font-size: 21px;
-}
-.datepicker thead tr:first-child th {
- cursor: pointer;
-}
-.datepicker thead tr:first-child th:hover {
- background: #eeeeee;
-}
-.input-append.date .add-on i,
-.input-prepend.date .add-on i {
- display: block;
- cursor: pointer;
- width: 16px;
- height: 16px;
-} \ No newline at end of file
diff --git a/openstack_dashboard/static/bootstrap/less/dropdowns.less b/openstack_dashboard/static/bootstrap/less/dropdowns.less
deleted file mode 100644
index a2a26fd9..00000000
--- a/openstack_dashboard/static/bootstrap/less/dropdowns.less
+++ /dev/null
@@ -1,130 +0,0 @@
-// DROPDOWN MENUS
-// --------------
-
-// Use the .menu class on any <li> element within the topbar or ul.tabs and you'll get some superfancy dropdowns
-.dropdown {
- position: relative;
-}
-.dropdown-toggle {
- // The caret makes the toggle a bit too tall in IE7
- *margin-bottom: -3px;
-}
-.dropdown-toggle:active,
-.open .dropdown-toggle {
- outline: 0;
-}
-// Dropdown arrow/caret
-.caret {
- display: inline-block;
- width: 0;
- height: 0;
- text-indent: -99999px;
- // IE7 won't do the border trick if there's a text indent, but it doesn't
- // do the content that text-indent is hiding, either, so we're ok.
- *text-indent: 0;
- vertical-align: top;
- border-left: 4px solid transparent;
- border-right: 4px solid transparent;
- border-top: 4px solid @black;
- .opacity(30);
- content: "\2193";
-}
-.dropdown .caret {
- margin-top: 8px;
- margin-left: 2px;
-}
-.dropdown:hover .caret,
-.open.dropdown .caret {
- .opacity(100);
-}
-// The dropdown menu (ul)
-.dropdown-menu {
- position: absolute;
- top: 100%;
- left: 0;
- z-index: @zindexDropdown;
- float: left;
- display: none; // none by default, but block on "open" of the menu
- min-width: 160px;
- _width: 160px;
- padding: 4px 0;
- margin: 0; // override default ul
- list-style: none;
- background-color: @white;
- border-color: #ccc;
- border-color: rgba(0,0,0,.2);
- border-style: solid;
- border-width: 1px;
- .border-radius(0 0 5px 5px);
- .box-shadow(0 5px 10px rgba(0,0,0,.2));
- -webkit-background-clip: padding-box;
- -moz-background-clip: padding;
- background-clip: padding-box;
- *border-right-width: 2px;
- *border-bottom-width: 2px;
-
- // Allow for dropdowns to go bottom up (aka, dropup-menu)
- &.bottom-up {
- top: auto;
- bottom: 100%;
- margin-bottom: 2px;
- }
-
- // Dividers (basically an hr) within the dropdown
- .divider {
- height: 1px;
- margin: 5px 1px;
- overflow: hidden;
- background-color: #e5e5e5;
- border-bottom: 1px solid @white;
-
- // IE7 needs a set width since we gave a height. Restricting just
- // to IE7 to keep the 1px left/right space in other browsers.
- // It is unclear where IE is getting the extra space that we need
- // to negative-margin away, but so it goes.
- *width: 100%;
- *margin: -5px 0 5px;
- }
-
- // Links within the dropdown menu
- a {
- display: block;
- padding: 3px 15px;
- clear: both;
- font-weight: normal;
- line-height: @baseLineHeight;
- color: @gray;
- word-wrap: break-word;
- }
-}
-
-// Hover state
-.dropdown-menu li > a:hover,
-.dropdown-menu .active > a,
-.dropdown-menu .active > a:hover {
- color: @white;
- text-decoration: none;
- background-color: @linkColor;
-}
-
-// Open state for the dropdown
-.dropdown.open {
- // IE7's z-index only goes to the nearest positioned ancestor, which would
- // make the menu appear below buttons that appeared later on the page
- *z-index: @zindexDropdown;
-
- .dropdown-toggle {
- color: @white;
- background: #ccc;
- background: rgba(0,0,0,.3);
- }
- .dropdown-menu {
- display: block;
- }
-}
-
-// Typeahead
-.typeahead {
- margin-top: 2px; // give it some space to breathe
- .border-radius(4px);
-}
diff --git a/openstack_dashboard/static/bootstrap/less/forms.less b/openstack_dashboard/static/bootstrap/less/forms.less
deleted file mode 100644
index 0a5fa2b8..00000000
--- a/openstack_dashboard/static/bootstrap/less/forms.less
+++ /dev/null
@@ -1,522 +0,0 @@
-// Forms.less
-// Base styles for various input types, form layouts, and states
-// -------------------------------------------------------------
-
-
-// GENERAL STYLES
-// --------------
-
-// Make all forms have space below them
-form {
- margin: 0 0 @baseLineHeight;
-}
-
-fieldset {
- padding: 0;
- margin: 0;
- border: 0;
-}
-
-// Groups of fields with labels on top (legends)
-legend {
- display: block;
- width: 100%;
- padding: 0;
- margin-bottom: @baseLineHeight * 1.5;
- font-size: @baseFontSize * 1.5;
- line-height: @baseLineHeight * 2;
- color: @grayDark;
- border: 0;
- border-bottom: 1px solid #eee;
-
- // Small
- small {
- font-size: @baseLineHeight * .75;
- color: @grayLight;
- }
-}
-
-// Set font for forms
-label,
-input,
-button,
-select,
-textarea {
- #font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here
-}
-input,
-button,
-select,
-textarea {
- #font > #family > .sans-serif(); // And only set font-family here for those that need it (note the missing label element)
-}
-
-// Identify controls by their labels
-label {
- display: block;
- margin-bottom: 5px;
- color: @grayDark;
-}
-
-// Inputs, Textareas, Selects
-input,
-textarea,
-select,
-.uneditable-input {
- display: inline-block;
- width: 210px;
- height: @baseLineHeight;
- padding: 4px;
- margin-bottom: 9px;
- font-size: @baseFontSize;
- line-height: @baseLineHeight;
- color: @gray;
- border: 1px solid #ccc;
- .border-radius(3px);
-}
-.uneditable-textarea {
- width: auto;
- height: auto;
-}
-
-// Inputs within a label
-label input,
-label textarea,
-label select {
- display: block;
-}
-
-// Mini reset for unique input types
-input[type="image"],
-input[type="checkbox"],
-input[type="radio"] {
- width: auto;
- height: auto;
- padding: 0;
- margin: 3px 0;
- *margin-top: 0; /* IE7 */
- line-height: normal;
- cursor: pointer;
- .border-radius(0);
- border: 0 \9; /* IE9 and down */
-}
-input[type="image"] {
- border: 0;
-}
-
-// Reset the file input to browser defaults
-input[type="file"] {
- width: auto;
- padding: initial;
- line-height: initial;
- border: initial;
- background-color: @white;
- background-color: initial;
- .box-shadow(none);
-}
-
-// Help out input buttons
-input[type="button"],
-input[type="reset"],
-input[type="submit"] {
- width: auto;
- height: auto;
-}
-
-// Set the height of select and file controls to match text inputs
-select,
-input[type="file"] {
- height: 28px; /* In IE7, the height of the select element cannot be changed by height, only font-size */
- *margin-top: 4px; /* For IE7, add top margin to align select with labels */
- line-height: 28px;
-}
-
-// Reset line-height for IE
-input[type="file"] {
- line-height: 18px \9;
-}
-
-// Chrome on Linux and Mobile Safari need background-color
-select {
- width: 220px; // default input width + 10px of padding that doesn't get applied
- background-color: @white;
-}
-
-// Make multiple select elements height not fixed
-select[multiple],
-select[size] {
- height: auto;
-}
-
-// Remove shadow from image inputs
-input[type="image"] {
- .box-shadow(none);
-}
-
-// Make textarea height behave
-textarea {
- height: auto;
-}
-
-// Hidden inputs
-input[type="hidden"] {
- display: none;
-}
-
-
-
-// CHECKBOXES & RADIOS
-// -------------------
-
-// Indent the labels to position radios/checkboxes as hanging
-.radio,
-.checkbox {
- padding-left: 18px;
-}
-.radio input[type="radio"],
-.checkbox input[type="checkbox"] {
- float: left;
- margin-left: -18px;
-}
-
-// Move the options list down to align with labels
-.controls > .radio:first-child,
-.controls > .checkbox:first-child {
- padding-top: 5px; // has to be padding because margin collaspes
-}
-
-// Radios and checkboxes on same line
-// TODO v3: Convert .inline to .control-inline
-.radio.inline,
-.checkbox.inline {
- display: inline-block;
- padding-top: 5px;
- margin-bottom: 0;
- vertical-align: middle;
-}
-.radio.inline + .radio.inline,
-.checkbox.inline + .checkbox.inline {
- margin-left: 10px; // space out consecutive inline controls
-}
-
-
-
-// FOCUS STATE
-// -----------
-
-input,
-textarea {
- .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
- @transition: border linear .2s, box-shadow linear .2s;
- .transition(@transition);
-}
-input:focus,
-textarea:focus {
- border-color: rgba(82,168,236,.8);
- @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);
- .box-shadow(@shadow);
- outline: 0;
- outline: thin dotted \9; /* IE6-9 */
-}
-input[type="file"]:focus,
-input[type="radio"]:focus,
-input[type="checkbox"]:focus,
-select:focus {
- .box-shadow(none); // override for file inputs
- .tab-focus();
-}
-
-
-
-// INPUT SIZES
-// -----------
-
-// General classes for quick sizes
-.input-mini { width: 60px; }
-.input-small { width: 90px; }
-.input-medium { width: 150px; }
-.input-large { width: 210px; }
-.input-xlarge { width: 270px; }
-.input-xxlarge { width: 530px; }
-
-// Grid style input sizes
-input[class*="span"],
-select[class*="span"],
-textarea[class*="span"],
-.uneditable-input {
- float: none;
- margin-left: 0;
-}
-
-
-
-// GRID SIZING FOR INPUTS
-// ----------------------
-
-#inputGridSystem > .generate(@gridColumns, @gridColumnWidth, @gridGutterWidth);
-
-
-
-
-// DISABLED STATE
-// --------------
-
-// Disabled and read-only inputs
-input[disabled],
-select[disabled],
-textarea[disabled],
-input[readonly],
-select[readonly],
-textarea[readonly] {
- background-color: #f5f5f5;
- border-color: #ddd;
- cursor: not-allowed;
-}
-
-
-
-
-// FORM FIELD FEEDBACK STATES
-// --------------------------
-
-// Warning
-.control-group.warning {
- .formFieldState(@warningText, @warningText, @warningBackground);
-}
-// Error
-.control-group.error {
- .formFieldState(@errorText, @errorText, @errorBackground);
-}
-// Success
-.control-group.success {
- .formFieldState(@successText, @successText, @successBackground);
-}
-
-// HTML5 invalid states
-// Shares styles with the .control-group.error above
-input:focus:required:invalid,
-textarea:focus:required:invalid,
-select:focus:required:invalid {
- color: #b94a48;
- border-color: #ee5f5b;
- &:focus {
- border-color: darken(#ee5f5b, 10%);
- .box-shadow(0 0 6px lighten(#ee5f5b, 20%));
- }
-}
-
-
-
-// FORM ACTIONS
-// ------------
-
-.form-actions {
- padding: (@baseLineHeight - 1) 20px @baseLineHeight;
- margin-top: @baseLineHeight;
- margin-bottom: @baseLineHeight;
- background-color: #f5f5f5;
- border-top: 1px solid #ddd;
-}
-
-// For text that needs to appear as an input but should not be an input
-.uneditable-input {
- display: block;
- background-color: @white;
- border-color: #eee;
- .box-shadow(inset 0 1px 2px rgba(0,0,0,.025));
- cursor: not-allowed;
-}
-
-// Placeholder text gets special styles; can't be bundled together though for some reason
-.placeholder(@grayLight);
-
-
-
-// HELP TEXT
-// ---------
-
-.help-block {
- display: block; // account for any element using help-block
- margin-top: 5px;
- margin-bottom: 0;
- color: @grayLight;
-}
-
-.help-inline {
- display: inline-block;
- .ie7-inline-block();
- margin-bottom: 9px;
- vertical-align: middle;
- padding-left: 5px;
-}
-
-
-
-// INPUT GROUPS
-// ------------
-
-// Allow us to put symbols and text within the input field for a cleaner look
-.input-prepend,
-.input-append {
- margin-bottom: 5px;
- .clearfix(); // Clear the float to prevent wrapping
- input,
- .uneditable-input {
- .border-radius(0 3px 3px 0);
- &:focus {
- position: relative;
- z-index: 2;
- }
- }
- .uneditable-input {
- border-left-color: #ccc;
- }
- .add-on {
- float: left;
- display: block;
- width: auto;
- min-width: 16px;
- height: @baseLineHeight;
- margin-right: -1px;
- padding: 4px 5px;
- font-weight: normal;
- line-height: @baseLineHeight;
- color: @grayLight;
- text-align: center;
- text-shadow: 0 1px 0 @white;
- background-color: #f5f5f5;
- border: 1px solid #ccc;
- .border-radius(3px 0 0 3px);
- }
- .active {
- background-color: lighten(@green, 30);
- border-color: @green;
- }
-}
-.input-prepend {
- .add-on {
- *margin-top: 1px; /* IE6-7 */
- }
-}
-.input-append {
- input,
- .uneditable-input {
- float: left;
- .border-radius(3px 0 0 3px);
- }
- .uneditable-input {
- border-left-color: #eee;
- border-right-color: #ccc;
- }
- .add-on {
- margin-right: 0;
- margin-left: -1px;
- .border-radius(0 3px 3px 0);
- }
- input:first-child {
- // In IE7, having a hasLayout container (from clearfix's zoom:1) can make the first input
- // inherit the sum of its ancestors' margins.
- *margin-left: -160px;
-
- &+.add-on {
- *margin-left: -21px;
- }
- }
-}
-
-
-
-// SEARCH FORM
-// -----------
-
-.search-query {
- padding-left: 14px;
- padding-right: 14px;
- margin-bottom: 0; // remove the default margin on all inputs
- .border-radius(14px);
-}
-
-
-
-// HORIZONTAL & VERTICAL FORMS
-// ---------------------------
-
-// Common properties
-// -----------------
-
-.form-search,
-.form-inline,
-.form-horizontal {
- input,
- textarea,
- select,
- .help-inline,
- .uneditable-input {
- display: inline-block;
- margin-bottom: 0;
- }
- // Re-hide hidden elements due to specifity
- .hide {
- display: none;
- }
-}
-.form-search label,
-.form-inline label,
-.form-search .input-append,
-.form-inline .input-append,
-.form-search .input-prepend,
-.form-inline .input-prepend {
- display: inline-block;
-}
-// Make the prepend and append add-on vertical-align: middle;
-.form-search .input-append .add-on,
-.form-inline .input-prepend .add-on,
-.form-search .input-append .add-on,
-.form-inline .input-prepend .add-on {
- vertical-align: middle;
-}
-// Inline checkbox/radio labels
-.form-search .radio,
-.form-inline .radio,
-.form-search .checkbox,
-.form-inline .checkbox {
- margin-bottom: 0;
- vertical-align: middle;
-}
-
-// Margin to space out fieldsets
-.control-group {
- margin-bottom: @baseLineHeight / 2;
-}
-
-// Legend collapses margin, so next element is responsible for spacing
-legend + .control-group {
- margin-top: @baseLineHeight;
- -webkit-margin-top-collapse: separate;
-}
-
-// Horizontal-specific styles
-// --------------------------
-
-.form-horizontal {
- // Increase spacing between groups
- .control-group {
- margin-bottom: @baseLineHeight;
- .clearfix();
- }
- // Float the labels left
- .control-label {
- float: left;
- width: 140px;
- padding-top: 5px;
- text-align: right;
- }
- // Move over all input controls and content
- .controls {
- margin-left: 160px;
- }
- // Move over buttons in .form-actions to align with .controls
- .form-actions {
- padding-left: 160px;
- }
-}
diff --git a/openstack_dashboard/static/bootstrap/less/grid.less b/openstack_dashboard/static/bootstrap/less/grid.less
deleted file mode 100644
index 4acb0a44..00000000
--- a/openstack_dashboard/static/bootstrap/less/grid.less
+++ /dev/null
@@ -1,8 +0,0 @@
-// GRID SYSTEM
-// -----------
-
-// Fixed (940px)
-#gridSystem > .generate(@gridColumns, @gridColumnWidth, @gridGutterWidth);
-
-// Fluid (940px)
-#fluidGridSystem > .generate(@gridColumns, @fluidGridColumnWidth, @fluidGridGutterWidth);
diff --git a/openstack_dashboard/static/bootstrap/less/hero-unit.less b/openstack_dashboard/static/bootstrap/less/hero-unit.less
deleted file mode 100644
index cba1cc46..00000000
--- a/openstack_dashboard/static/bootstrap/less/hero-unit.less
+++ /dev/null
@@ -1,20 +0,0 @@
-// HERO UNIT
-// ---------
-
-.hero-unit {
- padding: 60px;
- margin-bottom: 30px;
- background-color: #f5f5f5;
- .border-radius(6px);
- h1 {
- margin-bottom: 0;
- font-size: 60px;
- line-height: 1;
- letter-spacing: -1px;
- }
- p {
- font-size: 18px;
- font-weight: 200;
- line-height: @baseLineHeight * 1.5;
- }
-}
diff --git a/openstack_dashboard/static/bootstrap/less/labels.less b/openstack_dashboard/static/bootstrap/less/labels.less
deleted file mode 100644
index 268435a0..00000000
--- a/openstack_dashboard/static/bootstrap/less/labels.less
+++ /dev/null
@@ -1,32 +0,0 @@
-// LABELS
-// ------
-
-// Base
-.label {
- padding: 2px 4px 3px;
- font-size: @baseFontSize * .85;
- font-weight: bold;
- color: @white;
- text-shadow: 0 -1px 0 rgba(0,0,0,.25);
- background-color: @grayLight;
- .border-radius(3px);
-}
-
-// Hover state
-.label:hover {
- color: @white;
- text-decoration: none;
-}
-
-// Colors
-.label-important { background-color: @errorText; }
-.label-important:hover { background-color: darken(@errorText, 10%); }
-
-.label-warning { background-color: @orange; }
-.label-warning:hover { background-color: darken(@orange, 10%); }
-
-.label-success { background-color: @successText; }
-.label-success:hover { background-color: darken(@successText, 10%); }
-
-.label-info { background-color: @infoText; }
-.label-info:hover { background-color: darken(@infoText, 10%); }
diff --git a/openstack_dashboard/static/bootstrap/less/layouts.less b/openstack_dashboard/static/bootstrap/less/layouts.less
deleted file mode 100644
index c8d358b2..00000000
--- a/openstack_dashboard/static/bootstrap/less/layouts.less
+++ /dev/null
@@ -1,17 +0,0 @@
-//
-// Layouts
-// Fixed-width and fluid (with sidebar) layouts
-// --------------------------------------------
-
-
-// Container (centered, fixed-width layouts)
-.container {
- .container-fixed();
-}
-
-// Fluid layouts (left aligned, with sidebar, min- & max-width content)
-.container-fluid {
- padding-left: @gridGutterWidth;
- padding-right: @gridGutterWidth;
- .clearfix();
-} \ No newline at end of file
diff --git a/openstack_dashboard/static/bootstrap/less/mixins.less b/openstack_dashboard/static/bootstrap/less/mixins.less
deleted file mode 100644
index 3cf1a370..00000000
--- a/openstack_dashboard/static/bootstrap/less/mixins.less
+++ /dev/null
@@ -1,590 +0,0 @@
-// Mixins.less
-// Snippets of reusable CSS to develop faster and keep code readable
-// -----------------------------------------------------------------
-
-
-// UTILITY MIXINS
-// --------------------------------------------------
-
-// Clearfix
-// --------
-// For clearing floats like a boss h5bp.com/q
-.clearfix {
- *zoom: 1;
- &:before,
- &:after {
- display: table;
- content: "";
- }
- &:after {
- clear: both;
- }
-}
-
-// Webkit-style focus
-// ------------------
-.tab-focus() {
- // Default
- outline: thin dotted #333;
- // Webkit
- outline: 5px auto -webkit-focus-ring-color;
- outline-offset: -2px;
-}
-
-// Center-align a block level element
-// ----------------------------------
-.center-block() {
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-
-// IE7 inline-block
-// ----------------
-.ie7-inline-block() {
- *display: inline; /* IE7 inline-block hack */
- *zoom: 1;
-}
-
-// IE7 likes to collapse whitespace on either side of the inline-block elements.
-// Ems because we're attempting to match the width of a space character. Left
-// version is for form buttons, which typically come after other elements, and
-// right version is for icons, which come before. Applying both is ok, but it will
-// mean that space between those elements will be .6em (~2 space characters) in IE7,
-// instead of the 1 space in other browsers.
-.ie7-restore-left-whitespace() {
- *margin-left: .3em;
-
- &:first-child {
- *margin-left: 0;
- }
-}
-
-.ie7-restore-right-whitespace() {
- *margin-right: .3em;
-
- &:last-child {
- *margin-left: 0;
- }
-}
-
-// Sizing shortcuts
-// -------------------------
-.size(@height: 5px, @width: 5px) {
- width: @width;
- height: @height;
-}
-.square(@size: 5px) {
- .size(@size, @size);
-}
-
-// Placeholder text
-// -------------------------
-.placeholder(@color: @placeholderText) {
- :-moz-placeholder {
- color: @color;
- }
- ::-webkit-input-placeholder {
- color: @color;
- }
-}
-
-// Text overflow
-// -------------------------
-// Requires inline-block or block for proper styling
-.text-overflow() {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-
-
-// FONTS
-// --------------------------------------------------
-
-#font {
- #family {
- .serif() {
- font-family: Georgia, "Times New Roman", Times, serif;
- }
- .sans-serif() {
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- }
- .monospace() {
- font-family: Menlo, Monaco, "Courier New", monospace;
- }
- }
- .shorthand(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
- font-size: @size;
- font-weight: @weight;
- line-height: @lineHeight;
- }
- .serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
- #font > #family > .serif;
- #font > .shorthand(@size, @weight, @lineHeight);
- }
- .sans-serif(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
- #font > #family > .sans-serif;
- #font > .shorthand(@size, @weight, @lineHeight);
- }
- .monospace(@size: @baseFontSize, @weight: normal, @lineHeight: @baseLineHeight) {
- #font > #family > .monospace;
- #font > .shorthand(@size, @weight, @lineHeight);
- }
-}
-
-
-
-// GRID SYSTEM
-// --------------------------------------------------
-
-// Site container
-// -------------------------
-.container-fixed() {
- width: @gridRowWidth;
- margin-left: auto;
- margin-right: auto;
- .clearfix();
-}
-
-// Le grid system
-// -------------------------
-#gridSystem {
- // Setup the mixins to be used
- .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, @columns) {
- width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1));
- }
- .offset(@gridColumnWidth, @gridGutterWidth, @columns) {
- margin-left: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1)) + (@gridGutterWidth * 2);
- }
- .gridColumn(@gridGutterWidth) {
- float: left;
- margin-left: @gridGutterWidth;
- }
- // Take these values and mixins, and make 'em do their thang
- .generate(@gridColumns, @gridColumnWidth, @gridGutterWidth) {
- // Row surrounds the columns
- .row {
- margin-left: @gridGutterWidth * -1;
- .clearfix();
- }
- // Find all .span# classes within .row and give them the necessary properties for grid columns (supported by all browsers back to IE7, thanks @dhg)
- [class*="span"] {
- #gridSystem > .gridColumn(@gridGutterWidth);
- }
- // Default columns
- .span1 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 1); }
- .span2 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 2); }
- .span3 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 3); }
- .span4 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 4); }
- .span5 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 5); }
- .span6 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 6); }
- .span7 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 7); }
- .span8 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 8); }
- .span9 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 9); }
- .span10 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 10); }
- .span11 { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 11); }
- .span12,
- .container { #gridSystem > .columns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 12); }
- // Offset column options
- .offset1 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 1); }
- .offset2 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 2); }
- .offset3 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 3); }
- .offset4 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 4); }
- .offset5 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 5); }
- .offset6 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 6); }
- .offset7 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 7); }
- .offset8 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 8); }
- .offset9 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 9); }
- .offset10 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 10); }
- .offset11 { #gridSystem > .offset(@gridColumnWidth, @gridGutterWidth, 11); }
- }
-}
-
-// Fluid grid system
-// -------------------------
-#fluidGridSystem {
- // Setup the mixins to be used
- .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, @columns) {
- width: 1% * (@fluidGridColumnWidth * @columns) + (@fluidGridGutterWidth * (@columns - 1));
- }
- .gridColumn(@fluidGridGutterWidth) {
- float: left;
- margin-left: @fluidGridGutterWidth;
- }
- // Take these values and mixins, and make 'em do their thang
- .generate(@gridColumns, @fluidGridColumnWidth, @fluidGridGutterWidth) {
- // Row surrounds the columns
- .row-fluid {
- width: 100%;
- .clearfix();
-
- // Find all .span# classes within .row and give them the necessary properties for grid columns (supported by all browsers back to IE7, thanks @dhg)
- > [class*="span"] {
- #fluidGridSystem > .gridColumn(@fluidGridGutterWidth);
- }
- > [class*="span"]:first-child {
- margin-left: 0;
- }
- // Default columns
- > .span1 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 1); }
- > .span2 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 2); }
- > .span3 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 3); }
- > .span4 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 4); }
- > .span5 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 5); }
- > .span6 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 6); }
- > .span7 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 7); }
- > .span8 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 8); }
- > .span9 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 9); }
- > .span10 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 10); }
- > .span11 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 11); }
- > .span12 { #fluidGridSystem > .columns(@fluidGridGutterWidth, @fluidGridColumnWidth, 12); }
- }
- }
-}
-
-// Input grid system
-// -------------------------
-#inputGridSystem {
- .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, @columns) {
- width: ((@gridColumnWidth) * @columns) + (@gridGutterWidth * (@columns - 1)) - 10;
- }
- .generate(@gridColumns, @gridColumnWidth, @gridGutterWidth) {
- input,
- textarea,
- .uneditable-input {
- &.span1 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 1); }
- &.span2 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 2); }
- &.span3 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 3); }
- &.span4 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 4); }
- &.span5 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 5); }
- &.span6 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 6); }
- &.span7 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 7); }
- &.span8 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 8); }
- &.span9 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 9); }
- &.span10 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 10); }
- &.span11 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 11); }
- &.span12 { #inputGridSystem > .inputColumns(@gridGutterWidth, @gridColumnWidth, @gridRowWidth, 12); }
- }
- }
-}
-
-// Make a Grid
-// -------------------------
-// Use .makeRow and .makeColumn to assign semantic layouts grid system behavior
-.makeRow() {
- margin-left: @gridGutterWidth * -1;
- .clearfix();
-}
-.makeColumn(@columns: 1) {
- float: left;
- margin-left: @gridGutterWidth;
- width: (@gridColumnWidth * @columns) + (@gridGutterWidth * (@columns - 1));
-}
-
-
-
-// Form field states (used in forms.less)
-// --------------------------------------------------
-
-// Mixin for form field states
-.formFieldState(@textColor: #555, @borderColor: #ccc, @backgroundColor: #f5f5f5) {
- // Set the text color
- > label,
- .help-block,
- .help-inline {
- color: @textColor;
- }
- // Style inputs accordingly
- input,
- select,
- textarea {
- color: @textColor;
- border-color: @borderColor;
- &:focus {
- border-color: darken(@borderColor, 10%);
- .box-shadow(0 0 6px lighten(@borderColor, 20%));
- }
- }
- // Give a small background color for input-prepend/-append
- .input-prepend .add-on,
- .input-append .add-on {
- color: @textColor;
- background-color: @backgroundColor;
- border-color: @textColor;
- }
-}
-
-
-
-// CSS3 PROPERTIES
-// --------------------------------------------------
-
-// Border Radius
-.border-radius(@radius: 5px) {
- -webkit-border-radius: @radius;
- -moz-border-radius: @radius;
- border-radius: @radius;
-}
-
-// Drop shadows
-.box-shadow(@shadow: 0 1px 3px rgba(0,0,0,.25)) {
- -webkit-box-shadow: @shadow;
- -moz-box-shadow: @shadow;
- box-shadow: @shadow;
-}
-
-// Transitions
-.transition(@transition) {
- -webkit-transition: @transition;
- -moz-transition: @transition;
- -ms-transition: @transition;
- -o-transition: @transition;
- transition: @transition;
-}
-
-// Transformations
-.rotate(@degrees) {
- -webkit-transform: rotate(@degrees);
- -moz-transform: rotate(@degrees);
- -ms-transform: rotate(@degrees);
- -o-transform: rotate(@degrees);
- transform: rotate(@degrees);
-}
-.scale(@ratio) {
- -webkit-transform: scale(@ratio);
- -moz-transform: scale(@ratio);
- -ms-transform: scale(@ratio);
- -o-transform: scale(@ratio);
- transform: scale(@ratio);
-}
-.translate(@x: 0, @y: 0) {
- -webkit-transform: translate(@x, @y);
- -moz-transform: translate(@x, @y);
- -ms-transform: translate(@x, @y);
- -o-transform: translate(@x, @y);
- transform: translate(@x, @y);
-}
-.skew(@x: 0, @y: 0) {
- -webkit-transform: skew(@x, @y);
- -moz-transform: skew(@x, @y);
- -ms-transform: skew(@x, @y);
- -o-transform: skew(@x, @y);
- transform: skew(@x, @y);
-}
-.translate3d(@x: 0, @y: 0, @z: 0) {
- -webkit-transform: translate(@x, @y, @z);
- -moz-transform: translate(@x, @y, @z);
- -ms-transform: translate(@x, @y, @z);
- -o-transform: translate(@x, @y, @z);
- transform: translate(@x, @y, @z);
-}
-
-// Background clipping
-// Heads up: FF 3.6 and under need "padding" instead of "padding-box"
-.background-clip(@clip) {
- -webkit-background-clip: @clip;
- -moz-background-clip: @clip;
- background-clip: @clip;
-}
-
-// Background sizing
-.background-size(@size){
- -webkit-background-size: @size;
- -moz-background-size: @size;
- -o-background-size: @size;
- background-size: @size;
-}
-
-
-// Box sizing
-.box-sizing(@boxmodel) {
- -webkit-box-sizing: @boxmodel;
- -moz-box-sizing: @boxmodel;
- box-sizing: @boxmodel;
-}
-
-// User select
-// For selecting text on the page
-.user-select(@select) {
- -webkit-user-select: @select;
- -moz-user-select: @select;
- -o-user-select: @select;
- user-select: @select;
-}
-
-// Resize anything
-.resizable(@direction: both) {
- resize: @direction; // Options: horizontal, vertical, both
- overflow: auto; // Safari fix
-}
-
-// CSS3 Content Columns
-.content-columns(@columnCount, @columnGap: @gridColumnGutter) {
- -webkit-column-count: @columnCount;
- -moz-column-count: @columnCount;
- column-count: @columnCount;
- -webkit-column-gap: @columnGap;
- -moz-column-gap: @columnGap;
- column-gap: @columnGap;
-}
-
-// Opacity
-.opacity(@opacity: 100) {
- opacity: @opacity / 100;
- filter: e(%("alpha(opacity=%d)", @opacity));
-}
-
-
-
-// BACKGROUNDS
-// --------------------------------------------------
-
-// Add an alphatransparency value to any background or border color (via Elyse Holladay)
-#translucent {
- .background(@color: @white, @alpha: 1) {
- background-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha);
- }
- .border(@color: @white, @alpha: 1) {
- border-color: hsla(hue(@color), saturation(@color), lightness(@color), @alpha);
- .background-clip(padding-box);
- }
-}
-
-// Gradient Bar Colors for buttons and alerts
-.gradientBar(@primaryColor, @secondaryColor) {
- #gradient > .vertical(@primaryColor, @secondaryColor);
- border-color: @secondaryColor @secondaryColor darken(@secondaryColor, 15%);
- border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) fadein(rgba(0,0,0,.1), 15%);
-}
-
-// Gradients
-#gradient {
- .horizontal(@startColor: #555, @endColor: #333) {
- background-color: @endColor;
- background-image: -moz-linear-gradient(left, @startColor, @endColor); // FF 3.6+
- background-image: -ms-linear-gradient(left, @startColor, @endColor); // IE10
- background-image: -webkit-gradient(linear, 0 0, 100% 0, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+
- background-image: -webkit-linear-gradient(left, @startColor, @endColor); // Safari 5.1+, Chrome 10+
- background-image: -o-linear-gradient(left, @startColor, @endColor); // Opera 11.10
- background-image: linear-gradient(left, @startColor, @endColor); // Le standard
- background-repeat: repeat-x;
- filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",@startColor,@endColor)); // IE9 and down
- }
- .vertical(@startColor: #555, @endColor: #333) {
- background-color: mix(@startColor, @endColor, 60%);
- background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+
- background-image: -ms-linear-gradient(top, @startColor, @endColor); // IE10
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+
- background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+
- background-image: -o-linear-gradient(top, @startColor, @endColor); // Opera 11.10
- background-image: linear-gradient(top, @startColor, @endColor); // The standard
- background-repeat: repeat-x;
- filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@startColor,@endColor)); // IE9 and down
- }
- .directional(@startColor: #555, @endColor: #333, @deg: 45deg) {
- background-color: @endColor;
- background-repeat: repeat-x;
- background-image: -moz-linear-gradient(@deg, @startColor, @endColor); // FF 3.6+
- background-image: -ms-linear-gradient(@deg, @startColor, @endColor); // IE10
- background-image: -webkit-linear-gradient(@deg, @startColor, @endColor); // Safari 5.1+, Chrome 10+
- background-image: -o-linear-gradient(@deg, @startColor, @endColor); // Opera 11.10
- background-image: linear-gradient(@deg, @startColor, @endColor); // The standard
- }
- .vertical-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) {
- background-color: mix(@midColor, @endColor, 80%);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor));
- background-image: -webkit-linear-gradient(@startColor, @midColor @colorStop, @endColor);
- background-image: -moz-linear-gradient(top, @startColor, @midColor @colorStop, @endColor);
- background-image: -ms-linear-gradient(@startColor, @midColor @colorStop, @endColor);
- background-image: -o-linear-gradient(@startColor, @midColor @colorStop, @endColor);
- background-image: linear-gradient(@startColor, @midColor @colorStop, @endColor);
- background-repeat: no-repeat;
- filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@startColor,@endColor)); // IE9 and down, gets no color-stop at all for proper fallback
- }
- .radial(@innerColor: #555, @outerColor: #333) {
- background-color: @outerColor;
- background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(@innerColor), to(@outerColor));
- background-image: -webkit-radial-gradient(circle, @innerColor, @outerColor);
- background-image: -moz-radial-gradient(circle, @innerColor, @outerColor);
- background-image: -ms-radial-gradient(circle, @innerColor, @outerColor);
- background-repeat: no-repeat;
- // Opera cannot do radial gradients yet
- }
- .striped(@color, @angle: -45deg) {
- background-color: @color;
- background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent));
- background-image: -webkit-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
- background-image: -moz-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
- background-image: -ms-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
- background-image: -o-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
- }
-}
-// Reset filters for IE
-.reset-filter() {
- filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
-}
-
-
-// Mixin for generating button backgrounds
-// ---------------------------------------
-.buttonBackground(@startColor, @endColor) {
- // gradientBar will set the background to a pleasing blend of these, to support IE<=9
- .gradientBar(@startColor, @endColor);
- .reset-filter();
-
- // in these cases the gradient won't cover the background, so we override
- &:hover, &:active, &.active, &.disabled, &[disabled] {
- background-color: @endColor;
- }
-
- // IE 7 + 8 can't handle box-shadow to show active, so we darken a bit ourselves
- &:active,
- &.active {
- background-color: darken(@endColor, 10%) e("\9");
- }
-}
-
-
-// COMPONENT MIXINS
-// --------------------------------------------------
-
-// POPOVER ARROWS
-// -------------------------
-// For tipsies and popovers
-#popoverArrow {
- .top(@arrowWidth: 5px) {
- bottom: 0;
- left: 50%;
- margin-left: -@arrowWidth;
- border-left: @arrowWidth solid transparent;
- border-right: @arrowWidth solid transparent;
- border-top: @arrowWidth solid @black;
- }
- .left(@arrowWidth: 5px) {
- top: 50%;
- right: 0;
- margin-top: -@arrowWidth;
- border-top: @arrowWidth solid transparent;
- border-bottom: @arrowWidth solid transparent;
- border-left: @arrowWidth solid @black;
- }
- .bottom(@arrowWidth: 5px) {
- top: 0;
- left: 50%;
- margin-left: -@arrowWidth;
- border-left: @arrowWidth solid transparent;
- border-right: @arrowWidth solid transparent;
- border-bottom: @arrowWidth solid @black;
- }
- .right(@arrowWidth: 5px) {
- top: 50%;
- left: 0;
- margin-top: -@arrowWidth;
- border-top: @arrowWidth solid transparent;
- border-bottom: @arrowWidth solid transparent;
- border-right: @arrowWidth solid @black;
- }
-}
diff --git a/openstack_dashboard/static/bootstrap/less/modals.less b/openstack_dashboard/static/bootstrap/less/modals.less
deleted file mode 100644
index d1e06dc2..00000000
--- a/openstack_dashboard/static/bootstrap/less/modals.less
+++ /dev/null
@@ -1,83 +0,0 @@
-// MODALS
-// ------
-
-// Recalculate z-index where appropriate
-.modal-open {
- .dropdown-menu { z-index: @zindexDropdown + @zindexModal; }
- .dropdown.open { *z-index: @zindexDropdown + @zindexModal; }
- .popover { z-index: @zindexPopover + @zindexModal; }
- .tooltip { z-index: @zindexTooltip + @zindexModal; }
-}
-
-// Background
-.modal-backdrop {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: @zindexModalBackdrop;
- background-color: @black;
- // Fade for backdrop
- &.fade { opacity: 0; }
-}
-
-.modal-backdrop,
-.modal-backdrop.fade.in {
- .opacity(80);
-}
-
-// Base modal
-.modal {
- position: fixed;
- top: 50%;
- left: 50%;
- z-index: @zindexModal;
- max-height: 500px;
- overflow: auto;
- width: 560px;
- margin: -250px 0 0 -280px;
- background-color: @white;
- border: 1px solid #999;
- border: 1px solid rgba(0,0,0,.3);
- *border: 1px solid #999; /* IE6-7 */
- .border-radius(6px);
- .box-shadow(0 3px 7px rgba(0,0,0,0.3));
- .background-clip(padding-box);
- &.fade {
- .transition(e('opacity .3s linear, top .3s ease-out'));
- top: -25%;
- }
- &.fade.in { top: 50%; }
-}
-.modal-header {
- padding: 9px 15px;
- border-bottom: 1px solid #eee;
- // Close icon
- .close { margin-top: 2px; }
-}
-
-// Body (where all modal content resises)
-.modal-body {
- padding: 15px;
-}
-// Remove bottom margin if need be
-.modal-body .modal-form {
- margin-bottom: 0;
-}
-
-// Footer (for actions)
-.modal-footer {
- padding: 14px 15px 15px;
- margin-bottom: 0;
- background-color: #f5f5f5;
- border-top: 1px solid #ddd;
- .border-radius(0 0 6px 6px);
- .box-shadow(inset 0 1px 0 @white);
- .clearfix();
- .btn {
- float: right;
- margin-left: 5px;
- margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
- }
-}
diff --git a/openstack_dashboard/static/bootstrap/less/navbar.less b/openstack_dashboard/static/bootstrap/less/navbar.less
deleted file mode 100644
index 87a0f3a8..00000000
--- a/openstack_dashboard/static/bootstrap/less/navbar.less
+++ /dev/null
@@ -1,299 +0,0 @@
-// NAVBAR (FIXED AND STATIC)
-// -------------------------
-
-
-// COMMON STYLES
-// -------------
-
-.navbar {
- overflow: visible;
- margin-bottom: @baseLineHeight;
-}
-
-// Gradient is applied to it's own element because overflow visible is not honored by IE when filter is present
-.navbar-inner {
- padding-left: 20px;
- padding-right: 20px;
- #gradient > .vertical(@navbarBackgroundHighlight, @navbarBackground);
- .border-radius(4px);
- @shadow: 0 1px 3px rgba(0,0,0,.25), inset 0 -1px 0 rgba(0,0,0,.1);
- .box-shadow(@shadow);
-}
-
-// Navbar button for toggling navbar items in responsive layouts
-.btn-navbar {
- display: none;
- float: right;
- padding: 7px 10px;
- margin-left: 5px;
- margin-right: 5px;
- .buttonBackground(@navbarBackgroundHighlight, @navbarBackground);
- @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);
- .box-shadow(@shadow);
-}
-.btn-navbar .icon-bar {
- display: block;
- width: 18px;
- height: 2px;
- background-color: #f5f5f5;
- .border-radius(1px);
- .box-shadow(0 1px 0 rgba(0,0,0,.25));
-}
-.btn-navbar .icon-bar + .icon-bar {
- margin-top: 3px;
-}
-// Override the default collapsed state
-.nav-collapse.collapse {
- height: auto;
-}
-
-
-// Brand, links, text, and buttons
-.navbar {
- // Hover and active states
- .brand:hover {
- text-decoration: none;
- }
- // Website or project name
- .brand {
- float: left;
- display: block;
- padding: 8px 20px 12px;
- margin-left: -20px; // negative indent to left-align the text down the page
- font-size: 20px;
- font-weight: 200;
- line-height: 1;
- color: @white;
- }
- // Plain text in topbar
- .navbar-text {
- margin-bottom: 0;
- line-height: 40px;
- color: @navbarText;
- a:hover {
- color: @white;
- background-color: transparent;
- }
- }
- // Buttons in navbar
- .btn,
- .btn-group {
- margin-top: 5px; // make buttons vertically centered in navbar
- }
- .btn-group .btn {
- margin-top: 0; // then undo the margin here so we don't accidentally double it
- }
-}
-
-// Navbar forms
-.navbar-form {
- margin-bottom: 0; // remove default bottom margin
- .clearfix();
- input,
- select {
- display: inline-block;
- margin-top: 5px;
- margin-bottom: 0;
- }
- .radio,
- .checkbox {
- margin-top: 5px;
- }
- input[type="image"],
- input[type="checkbox"],
- input[type="radio"] {
- margin-top: 3px;
- }
- .input-append,
- .input-prepend {
- margin-top: 6px;
- white-space: nowrap; // preven two items from separating within a .navbar-form that has .pull-left
- input {
- margin-top: 0; // remove the margin on top since it's on the parent
- }
- }
-}
-
-// Navbar search
-.navbar-search {
- position: relative;
- float: left;
- margin-top: 6px;
- margin-bottom: 0;
- .search-query {
- padding: 4px 9px;
- #font > .sans-serif(13px, normal, 1);
- color: @white;
- color: rgba(255,255,255,.75);
- background: #666;
- background: rgba(255,255,255,.3);
- border: 1px solid #111;
- @shadow: inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);
- .box-shadow(@shadow);
- .transition(none);
-
- // Placeholder text gets special styles; can't be bundled together though for some reason
- .placeholder(@grayLighter);
-
- // Hover states
- &:hover {
- color: @white;
- background-color: @grayLight;
- background-color: rgba(255,255,255,.5);
- }
- // Focus states (we use .focused since IE7-8 and down doesn't support :focus)
- &:focus,
- &.focused {
- padding: 5px 10px;
- color: @grayDark;
- text-shadow: 0 1px 0 @white;
- background-color: @white;
- border: 0;
- .box-shadow(0 0 3px rgba(0,0,0,.15));
- outline: 0;
- }
- }
-}
-
-
-// FIXED NAVBAR
-// ------------
-
-.navbar-fixed-top {
- position: fixed;
- top: 0;
- right: 0;
- left: 0;
- z-index: @zindexFixedNavbar;
-}
-.navbar-fixed-top .navbar-inner {
- padding-left: 0;
- padding-right: 0;
- .border-radius(0);
-}
-
-
-// NAVIGATION
-// ----------
-
-.navbar .nav {
- position: relative;
- left: 0;
- display: block;
- float: left;
- margin: 0 10px 0 0;
-}
-.navbar .nav.pull-right {
- float: right; // redeclare due to specificity
-}
-.navbar .nav > li {
- display: block;
- float: left;
-}
-
-// Links
-.navbar .nav > li > a {
- float: none;
- padding: 10px 10px 11px;
- line-height: 19px;
- color: @navbarLinkColor;
- text-decoration: none;
- text-shadow: 0 -1px 0 rgba(0,0,0,.25);
-}
-// Hover
-.navbar .nav > li > a:hover {
- background-color: @navbarLinkBackgroundHover; // "transparent" is default to differentiate :hover from .active
- color: @navbarLinkColorHover;
- text-decoration: none;
-}
-
-// Active nav items
-.navbar .nav .active > a,
-.navbar .nav .active > a:hover {
- color: @navbarLinkColorHover;
- text-decoration: none;
- background-color: @navbarBackground;
-}
-
-// Dividers (basically a vertical hr)
-.navbar .divider-vertical {
- height: @navbarHeight;
- width: 1px;
- margin: 0 9px;
- overflow: hidden;
- background-color: @navbarBackground;
- border-right: 1px solid @navbarBackgroundHighlight;
-}
-
-// Secondary (floated right) nav in topbar
-.navbar .nav.pull-right {
- margin-left: 10px;
- margin-right: 0;
-}
-
-
-
-// Dropdown menus
-// --------------
-
-// Menu position and menu carets
-.navbar .dropdown-menu {
- margin-top: 1px;
- .border-radius(4px);
- &:before {
- content: '';
- display: inline-block;
- border-left: 7px solid transparent;
- border-right: 7px solid transparent;
- border-bottom: 7px solid #ccc;
- border-bottom-color: rgba(0,0,0,.2);
- position: absolute;
- top: -7px;
- left: 9px;
- }
- &:after {
- content: '';
- display: inline-block;
- border-left: 6px solid transparent;
- border-right: 6px solid transparent;
- border-bottom: 6px solid @white;
- position: absolute;
- top: -6px;
- left: 10px;
- }
-}
-
-// Dropdown toggle caret
-.navbar .nav .dropdown-toggle .caret,
-.navbar .nav .open.dropdown .caret {
- border-top-color: @white;
-}
-.navbar .nav .active .caret {
- .opacity(100);
-}
-
-// Remove background color from open dropdown
-.navbar .nav .open > .dropdown-toggle,
-.navbar .nav .active > .dropdown-toggle,
-.navbar .nav .open.active > .dropdown-toggle {
- background-color: transparent;
-}
-
-// Dropdown link on hover
-.navbar .nav .active > .dropdown-toggle:hover {
- color: @white;
-}
-
-// Right aligned menus need alt position
-.navbar .nav.pull-right .dropdown-menu {
- left: auto;
- right: 0;
- &:before {
- left: auto;
- right: 12px;
- }
- &:after {
- left: auto;
- right: 13px;
- }
-}
diff --git a/openstack_dashboard/static/bootstrap/less/navs.less b/openstack_dashboard/static/bootstrap/less/navs.less
deleted file mode 100644
index 06219fa6..00000000
--- a/openstack_dashboard/static/bootstrap/less/navs.less
+++ /dev/null
@@ -1,353 +0,0 @@
-// NAVIGATIONS
-// -----------
-
-
-
-// BASE CLASS
-// ----------
-
-.nav {
- margin-left: 0;
- margin-bottom: @baseLineHeight;
- list-style: none;
-}
-
-// Make links block level
-.nav > li > a {
- display: block;
-}
-.nav > li > a:hover {
- text-decoration: none;
- background-color: @grayLighter;
-}
-
-// Nav headers (for dropdowns and lists)
-.nav .nav-header {
- display: block;
- padding: 3px 15px;
- font-size: 11px;
- font-weight: bold;
- line-height: @baseLineHeight;
- color: @grayLight;
- text-shadow: 0 1px 0 rgba(255,255,255,.5);
- text-transform: uppercase;
-}
-// Space them out when they follow another list item (link)
-.nav li + .nav-header {
- margin-top: 9px;
-}
-
-
-// NAV LIST
-// --------
-
-.nav-list {
- padding-left: 14px;
- padding-right: 14px;
- margin-bottom: 0;
-}
-.nav-list > li > a,
-.nav-list .nav-header {
- margin-left: -15px;
- margin-right: -15px;
- text-shadow: 0 1px 0 rgba(255,255,255,.5);
-}
-.nav-list > li > a {
- padding: 3px 15px;
-}
-.nav-list .active > a,
-.nav-list .active > a:hover {
- color: @white;
- text-shadow: 0 -1px 0 rgba(0,0,0,.2);
- background-color: @linkColor;
-}
-.nav-list [class^="icon-"] {
- margin-right: 2px;
-}
-
-
-
-// TABS AND PILLS
-// -------------
-
-// Common styles
-.nav-tabs,
-.nav-pills {
- .clearfix();
-}
-.nav-tabs > li,
-.nav-pills > li {
- float: left;
-}
-.nav-tabs > li > a,
-.nav-pills > li > a {
- padding-right: 12px;
- padding-left: 12px;
- margin-right: 2px;
- line-height: 14px; // keeps the overall height an even number
-}
-
-// TABS
-// ----
-
-// Give the tabs something to sit on
-.nav-tabs {
- border-bottom: 1px solid #ddd;
-}
-
-// Make the list-items overlay the bottom border
-.nav-tabs > li {
- margin-bottom: -1px;
-}
-
-// Actual tabs (as links)
-.nav-tabs > li > a {
- padding-top: 9px;
- padding-bottom: 9px;
- border: 1px solid transparent;
- .border-radius(4px 4px 0 0);
- &:hover {
- border-color: @grayLighter @grayLighter #ddd;
- }
-}
-// Active state, and it's :hover to override normal :hover
-.nav-tabs > .active > a,
-.nav-tabs > .active > a:hover {
- color: @gray;
- background-color: @white;
- border: 1px solid #ddd;
- border-bottom-color: transparent;
- cursor: default;
-}
-
-// PILLS
-// -----
-
-// Links rendered as pills
-.nav-pills > li > a {
- padding-top: 8px;
- padding-bottom: 8px;
- margin-top: 2px;
- margin-bottom: 2px;
- .border-radius(5px);
-}
-
-// Active state
-.nav-pills .active > a,
-.nav-pills .active > a:hover {
- color: @white;
- background-color: @linkColor;
-}
-
-
-
-// STACKED NAV
-// -----------
-
-// Stacked tabs and pills
-.nav-stacked > li {
- float: none;
-}
-.nav-stacked > li > a {
- margin-right: 0; // no need for the gap between nav items
-}
-
-// Tabs
-.nav-tabs.nav-stacked {
- border-bottom: 0;
-}
-.nav-tabs.nav-stacked > li > a {
- border: 1px solid #ddd;
- .border-radius(0);
-}
-.nav-tabs.nav-stacked > li:first-child > a {
- .border-radius(4px 4px 0 0);
-}
-.nav-tabs.nav-stacked > li:last-child > a {
- .border-radius(0 0 4px 4px);
-}
-.nav-tabs.nav-stacked > li > a:hover {
- border-color: #ddd;
- z-index: 2;
-}
-
-// Pills
-.nav-pills.nav-stacked > li > a {
- margin-bottom: 3px;
-}
-.nav-pills.nav-stacked > li:last-child > a {
- margin-bottom: 1px; // decrease margin to match sizing of stacked tabs
-}
-
-
-
-// DROPDOWNS
-// ---------
-
-// Position the menu
-.nav-tabs .dropdown-menu,
-.nav-pills .dropdown-menu {
- margin-top: 1px;
- border-width: 1px;
-}
-.nav-pills .dropdown-menu {
- .border-radius(4px);
-}
-
-// Default dropdown links
-// -------------------------
-// Make carets use linkColor to start
-.nav-tabs .dropdown-toggle .caret,
-.nav-pills .dropdown-toggle .caret {
- border-top-color: @linkColor;
- margin-top: 6px;
-}
-.nav-tabs .dropdown-toggle:hover .caret,
-.nav-pills .dropdown-toggle:hover .caret {
- border-top-color: @linkColorHover;
-}
-
-// Active dropdown links
-// -------------------------
-.nav-tabs .active .dropdown-toggle .caret,
-.nav-pills .active .dropdown-toggle .caret {
- border-top-color: @grayDark;
-}
-
-// Active:hover dropdown links
-// -------------------------
-.nav > .dropdown.active > a:hover {
- color: @black;
- cursor: pointer;
-}
-
-// Open dropdowns
-// -------------------------
-.nav-tabs .open .dropdown-toggle,
-.nav-pills .open .dropdown-toggle,
-.nav > .open.active > a:hover {
- color: @white;
- background-color: @grayLight;
- border-color: @grayLight;
-}
-.nav .open .caret,
-.nav .open.active .caret,
-.nav .open a:hover .caret {
- border-top-color: @white;
- .opacity(100);
-}
-
-// Dropdowns in stacked tabs
-.tabs-stacked .open > a:hover {
- border-color: @grayLight;
-}
-
-
-
-// TABBABLE
-// --------
-
-
-// COMMON STYLES
-// -------------
-
-// Clear any floats
-.tabbable {
- .clearfix();
-}
-.tab-content {
- overflow: hidden; // prevent content from running below tabs
-}
-
-// Remove border on bottom, left, right
-.tabs-below .nav-tabs,
-.tabs-right .nav-tabs,
-.tabs-left .nav-tabs {
- border-bottom: 0;
-}
-
-// Show/hide tabbable areas
-.tab-content > .tab-pane,
-.pill-content > .pill-pane {
- display: none;
-}
-.tab-content > .active,
-.pill-content > .active {
- display: block;
-}
-
-
-// BOTTOM
-// ------
-
-.tabs-below .nav-tabs {
- border-top: 1px solid #ddd;
-}
-.tabs-below .nav-tabs > li {
- margin-top: -1px;
- margin-bottom: 0;
-}
-.tabs-below .nav-tabs > li > a {
- .border-radius(0 0 4px 4px);
- &:hover {
- border-bottom-color: transparent;
- border-top-color: #ddd;
- }
-}
-.tabs-below .nav-tabs .active > a,
-.tabs-below .nav-tabs .active > a:hover {
- border-color: transparent #ddd #ddd #ddd;
-}
-
-// LEFT & RIGHT
-// ------------
-
-// Common styles
-.tabs-left .nav-tabs > li,
-.tabs-right .nav-tabs > li {
- float: none;
-}
-.tabs-left .nav-tabs > li > a,
-.tabs-right .nav-tabs > li > a {
- min-width: 74px;
- margin-right: 0;
- margin-bottom: 3px;
-}
-
-// Tabs on the left
-.tabs-left .nav-tabs {
- float: left;
- margin-right: 19px;
- border-right: 1px solid #ddd;
-}
-.tabs-left .nav-tabs > li > a {
- margin-right: -1px;
- .border-radius(4px 0 0 4px);
-}
-.tabs-left .nav-tabs > li > a:hover {
- border-color: @grayLighter #ddd @grayLighter @grayLighter;
-}
-.tabs-left .nav-tabs .active > a,
-.tabs-left .nav-tabs .active > a:hover {
- border-color: #ddd transparent #ddd #ddd;
- *border-right-color: @white;
-}
-
-// Tabs on the right
-.tabs-right .nav-tabs {
- float: right;
- margin-left: 19px;
- border-left: 1px solid #ddd;
-}
-.tabs-right .nav-tabs > li > a {
- margin-left: -1px;
- .border-radius(0 4px 4px 0);
-}
-.tabs-right .nav-tabs > li > a:hover {
- border-color: @grayLighter @grayLighter @grayLighter #ddd;
-}
-.tabs-right .nav-tabs .active > a,
-.tabs-right .nav-tabs .active > a:hover {
- border-color: #ddd #ddd #ddd transparent;
- *border-left-color: @white;
-}
diff --git a/openstack_dashboard/static/bootstrap/less/pager.less b/openstack_dashboard/static/bootstrap/less/pager.less
deleted file mode 100644
index 104e41ca..00000000
--- a/openstack_dashboard/static/bootstrap/less/pager.less
+++ /dev/null
@@ -1,30 +0,0 @@
-// PAGER
-// -----
-
-.pager {
- margin-left: 0;
- margin-bottom: @baseLineHeight;
- list-style: none;
- text-align: center;
- .clearfix();
-}
-.pager li {
- display: inline;
-}
-.pager a {
- display: inline-block;
- padding: 5px 14px;
- background-color: #fff;
- border: 1px solid #ddd;
- .border-radius(15px);
-}
-.pager a:hover {
- text-decoration: none;
- background-color: #f5f5f5;
-}
-.pager .next a {
- float: right;
-}
-.pager .previous a {
- float: left;
-}
diff --git a/openstack_dashboard/static/bootstrap/less/pagination.less b/openstack_dashboard/static/bootstrap/less/pagination.less
deleted file mode 100644
index de578075..00000000
--- a/openstack_dashboard/static/bootstrap/less/pagination.less
+++ /dev/null
@@ -1,55 +0,0 @@
-// PAGINATION
-// ----------
-
-.pagination {
- height: @baseLineHeight * 2;
- margin: @baseLineHeight 0;
- }
-.pagination ul {
- display: inline-block;
- .ie7-inline-block();
- margin-left: 0;
- margin-bottom: 0;
- .border-radius(3px);
- .box-shadow(0 1px 2px rgba(0,0,0,.05));
-}
-.pagination li {
- display: inline;
- }
-.pagination a {
- float: left;
- padding: 0 14px;
- line-height: (@baseLineHeight * 2) - 2;
- text-decoration: none;
- border: 1px solid #ddd;
- border-left-width: 0;
-}
-.pagination a:hover,
-.pagination .active a {
- background-color: #f5f5f5;
-}
-.pagination .active a {
- color: @grayLight;
- cursor: default;
-}
-.pagination .disabled a,
-.pagination .disabled a:hover {
- color: @grayLight;
- background-color: transparent;
- cursor: default;
-}
-.pagination li:first-child a {
- border-left-width: 1px;
- .border-radius(3px 0 0 3px);
-}
-.pagination li:last-child a {
- .border-radius(0 3px 3px 0);
-}
-
-// Centered
-.pagination-centered {
- text-align: center;
-}
-.pagination-right {
- text-align: right;
-}
diff --git a/openstack_dashboard/static/bootstrap/less/popovers.less b/openstack_dashboard/static/bootstrap/less/popovers.less
deleted file mode 100644
index 558d99ec..00000000
--- a/openstack_dashboard/static/bootstrap/less/popovers.less
+++ /dev/null
@@ -1,49 +0,0 @@
-// POPOVERS
-// --------
-
-.popover {
- position: absolute;
- top: 0;
- left: 0;
- z-index: @zindexPopover;
- display: none;
- padding: 5px;
- &.top { margin-top: -5px; }
- &.right { margin-left: 5px; }
- &.bottom { margin-top: 5px; }
- &.left { margin-left: -5px; }
- &.top .arrow { #popoverArrow > .top(); }
- &.right .arrow { #popoverArrow > .right(); }
- &.bottom .arrow { #popoverArrow > .bottom(); }
- &.left .arrow { #popoverArrow > .left(); }
- .arrow {
- position: absolute;
- width: 0;
- height: 0;
- }
-}
-.popover-inner {
- padding: 3px;
- width: 280px;
- overflow: hidden;
- background: @black; // has to be full background declaration for IE fallback
- background: rgba(0,0,0,.8);
- .border-radius(6px);
- .box-shadow(0 3px 7px rgba(0,0,0,0.3));
-}
-.popover-title {
- padding: 9px 15px;
- line-height: 1;
- background-color: #f5f5f5;
- border-bottom:1px solid #eee;
- .border-radius(3px 3px 0 0);
-}
-.popover-content {
- padding: 14px;
- background-color: @white;
- .border-radius(0 0 3px 3px);
- .background-clip(padding-box);
- p, ul, ol {
- margin-bottom: 0;
- }
-}
diff --git a/openstack_dashboard/static/bootstrap/less/progress-bars.less b/openstack_dashboard/static/bootstrap/less/progress-bars.less
deleted file mode 100644
index c3144e1b..00000000
--- a/openstack_dashboard/static/bootstrap/less/progress-bars.less
+++ /dev/null
@@ -1,95 +0,0 @@
-// PROGRESS BARS
-// -------------
-
-
-// ANIMATIONS
-// ----------
-
-// Webkit
-@-webkit-keyframes progress-bar-stripes {
- from { background-position: 0 0; }
- to { background-position: 40px 0; }
-}
-
-// Firefox
-@-moz-keyframes progress-bar-stripes {
- from { background-position: 0 0; }
- to { background-position: 40px 0; }
-}
-
-// Spec
-@keyframes progress-bar-stripes {
- from { background-position: 0 0; }
- to { background-position: 40px 0; }
-}
-
-
-
-// THE BARS
-// --------
-
-// Outer container
-.progress {
- overflow: hidden;
- height: 18px;
- margin-bottom: 18px;
- #gradient > .vertical(#f5f5f5, #f9f9f9);
- .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
- .border-radius(4px);
-}
-
-// Bar of progress
-.progress .bar {
- width: 0%;
- height: 18px;
- color: @white;
- font-size: 12px;
- text-align: center;
- text-shadow: 0 -1px 0 rgba(0,0,0,.25);
- #gradient > .vertical(#149bdf, #0480be);
- .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));
- .box-sizing(border-box);
- .transition(width .6s ease);
-}
-
-// Striped bars
-.progress-striped .bar {
- #gradient > .striped(#62c462);
- .background-size(40px 40px);
-}
-
-// Call animation for the active one
-.progress.active .bar {
- -webkit-animation: progress-bar-stripes 2s linear infinite;
- -moz-animation: progress-bar-stripes 2s linear infinite;
- animation: progress-bar-stripes 2s linear infinite;
-}
-
-
-
-// COLORS
-// ------
-
-// Danger (red)
-.progress-danger .bar {
- #gradient > .vertical(#ee5f5b, #c43c35);
-}
-.progress-danger.progress-striped .bar {
- #gradient > .striped(#ee5f5b);
-}
-
-// Success (green)
-.progress-success .bar {
- #gradient > .vertical(#62c462, #57a957);
-}
-.progress-success.progress-striped .bar {
- #gradient > .striped(#62c462);
-}
-
-// Info (teal)
-.progress-info .bar {
- #gradient > .vertical(#5bc0de, #339bb9);
-}
-.progress-info.progress-striped .bar {
- #gradient > .striped(#5bc0de);
-}
diff --git a/openstack_dashboard/static/bootstrap/less/reset.less b/openstack_dashboard/static/bootstrap/less/reset.less
deleted file mode 100644
index 1115f59d..00000000
--- a/openstack_dashboard/static/bootstrap/less/reset.less
+++ /dev/null
@@ -1,126 +0,0 @@
-// Reset.less
-// Adapted from Normalize.css http://github.com/necolas/normalize.css
-// ------------------------------------------------------------------------
-
-// Display in IE6-9 and FF3
-// -------------------------
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-nav,
-section {
- display: block;
-}
-
-// Display block in IE6-9 and FF3
-// -------------------------
-
-audio,
-canvas,
-video {
- display: inline-block;
- *display: inline;
- *zoom: 1;
-}
-
-// Prevents modern browsers from displaying 'audio' without controls
-// -------------------------
-
-audio:not([controls]) {
- display: none;
-}
-
-// Base settings
-// -------------------------
-
-html {
- font-size: 100%;
- -webkit-text-size-adjust: 100%;
- -ms-text-size-adjust: 100%;
-}
-// Focus states
-a:focus {
- .tab-focus();
-}
-// Hover & Active
-a:hover,
-a:active {
- outline: 0;
-}
-
-// Prevents sub and sup affecting line-height in all browsers
-// -------------------------
-
-sub,
-sup {
- position: relative;
- font-size: 75%;
- line-height: 0;
- vertical-align: baseline;
-}
-sup {
- top: -0.5em;
-}
-sub {
- bottom: -0.25em;
-}
-
-// Img border in a's and image quality
-// -------------------------
-
-img {
- max-width: 100%;
- height: auto;
- border: 0;
- -ms-interpolation-mode: bicubic;
-}
-
-// Forms
-// -------------------------
-
-// Font size in all browsers, margin changes, misc consistency
-button,
-input,
-select,
-textarea {
- margin: 0;
- font-size: 100%;
- vertical-align: middle;
-}
-button,
-input {
- *overflow: visible; // Inner spacing ie IE6/7
- line-height: normal; // FF3/4 have !important on line-height in UA stylesheet
-}
-button::-moz-focus-inner,
-input::-moz-focus-inner { // Inner padding and border oddities in FF3/4
- padding: 0;
- border: 0;
-}
-button,
-input[type="button"],
-input[type="reset"],
-input[type="submit"] {
- cursor: pointer; // Cursors on all buttons applied consistently
- -webkit-appearance: button; // Style clickable inputs in iOS
-}
-input[type="search"] { // Appearance in Safari/Chrome
- -webkit-appearance: textfield;
- -webkit-box-sizing: content-box;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
-}
-input[type="search"]::-webkit-search-decoration,
-input[type="search"]::-webkit-search-cancel-button {
- -webkit-appearance: none; // Inner-padding issues in Chrome OSX, Safari 5
-}
-textarea {
- overflow: auto; // Remove vertical scrollbar in IE6-9
- vertical-align: top; // Readability and alignment cross-browser
-}
diff --git a/openstack_dashboard/static/bootstrap/less/responsive.less b/openstack_dashboard/static/bootstrap/less/responsive.less
deleted file mode 100644
index 1547dce9..00000000
--- a/openstack_dashboard/static/bootstrap/less/responsive.less
+++ /dev/null
@@ -1,327 +0,0 @@
-/*!
- * Bootstrap Responsive v2.0.1
- *
- * Copyright 2012 Twitter, Inc
- * Licensed under the Apache License v2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Designed and built with all the love in the world @twitter by @mdo and @fat.
- */
-
-// Responsive.less
-// For phone and tablet devices
-// -------------------------------------------------------------
-
-
-// REPEAT VARIABLES & MIXINS
-// -------------------------
-// Required since we compile the responsive stuff separately
-
-@import "variables.less"; // Modify this for custom colors, font-sizes, etc
-@import "mixins.less";
-
-
-// RESPONSIVE CLASSES
-// ------------------
-
-// Hide from screenreaders and browsers
-// Credit: HTML5 Boilerplate
-.hidden {
- display: none;
- visibility: hidden;
-}
-
-
-
-// UP TO LANDSCAPE PHONE
-// ---------------------
-
-@media (max-width: 480px) {
-
- // Smooth out the collapsing/expanding nav
- .nav-collapse {
- -webkit-transform: translate3d(0, 0, 0); // activate the GPU
- }
-
- // Block level the page header small tag for readability
- .page-header h1 small {
- display: block;
- line-height: @baseLineHeight;
- }
-
- // Make span* classes full width
- input[class*="span"],
- select[class*="span"],
- textarea[class*="span"],
- .uneditable-input {
- display: block;
- width: 100%;
- min-height: 28px; /* Make inputs at least the height of their button counterpart */
- /* Makes inputs behave like true block-level elements */
- -webkit-box-sizing: border-box; /* Older Webkit */
- -moz-box-sizing: border-box; /* Older FF */
- -ms-box-sizing: border-box; /* IE8 */
- box-sizing: border-box; /* CSS3 spec*/
- }
- // But don't let it screw up prepend/append inputs
- .input-prepend input[class*="span"],
- .input-append input[class*="span"] {
- width: auto;
- }
-
- // Update checkboxes for iOS
- input[type="checkbox"],
- input[type="radio"] {
- border: 1px solid #ccc;
- }
-
- // Remove the horizontal form styles
- .form-horizontal .control-group > label {
- float: none;
- width: auto;
- padding-top: 0;
- text-align: left;
- }
- // Move over all input controls and content
- .form-horizontal .controls {
- margin-left: 0;
- }
- // Move the options list down to align with labels
- .form-horizontal .control-list {
- padding-top: 0; // has to be padding because margin collaspes
- }
- // Move over buttons in .form-actions to align with .controls
- .form-horizontal .form-actions {
- padding-left: 10px;
- padding-right: 10px;
- }
-
- // Modals
- .modal {
- position: absolute;
- top: 10px;
- left: 10px;
- right: 10px;
- width: auto;
- margin: 0;
- &.fade.in { top: auto; }
- }
- .modal-header .close {
- padding: 10px;
- margin: -10px;
- }
-
- // Carousel
- .carousel-caption {
- position: static;
- }
-
-}
-
-
-
-// LANDSCAPE PHONE TO SMALL DESKTOP & PORTRAIT TABLET
-// --------------------------------------------------
-
-@media (max-width: 767px) {
- // GRID & CONTAINERS
- // -----------------
- // Remove width from containers
- .container {
- width: auto;
- padding: 0 20px;
- }
- // Fluid rows
- .row-fluid {
- width: 100%;
- }
- // Undo negative margin on rows
- .row {
- margin-left: 0;
- }
- // Make all columns even
- .row > [class*="span"],
- .row-fluid > [class*="span"] {
- float: none;
- display: block;
- width: auto;
- margin: 0;
- }
-}
-
-
-
-// PORTRAIT TABLET TO DEFAULT DESKTOP
-// ----------------------------------
-
-@media (min-width: 768px) and (max-width: 979px) {
-
- // Fixed grid
- #gridSystem > .generate(12, 42px, 20px);
-
- // Fluid grid
- #fluidGridSystem > .generate(12, 5.801104972%, 2.762430939%);
-
- // Input grid
- #inputGridSystem > .generate(12, 42px, 20px);
-
-}
-
-
-
-// TABLETS AND BELOW
-// -----------------
-@media (max-width: 979px) {
-
- // UNFIX THE TOPBAR
- // ----------------
- // Remove any padding from the body
- body {
- padding-top: 0;
- }
- // Unfix the navbar
- .navbar-fixed-top {
- position: static;
- margin-bottom: @baseLineHeight;
- }
- .navbar-fixed-top .navbar-inner {
- padding: 5px;
- }
- .navbar .container {
- width: auto;
- padding: 0;
- }
- // Account for brand name
- .navbar .brand {
- padding-left: 10px;
- padding-right: 10px;
- margin: 0 0 0 -5px;
- }
- // Nav collapse clears brand
- .navbar .nav-collapse {
- clear: left;
- }
- // Block-level the nav
- .navbar .nav {
- float: none;
- margin: 0 0 (@baseLineHeight / 2);
- }
- .navbar .nav > li {
- float: none;
- }
- .navbar .nav > li > a {
- margin-bottom: 2px;
- }
- .navbar .nav > .divider-vertical {
- display: none;
- }
- .navbar .nav .nav-header {
- color: @navbarText;
- text-shadow: none;
- }
- // Nav and dropdown links in navbar
- .navbar .nav > li > a,
- .navbar .dropdown-menu a {
- padding: 6px 15px;
- font-weight: bold;
- color: @navbarLinkColor;
- .border-radius(3px);
- }
- .navbar .dropdown-menu li + li a {
- margin-bottom: 2px;
- }
- .navbar .nav > li > a:hover,
- .navbar .dropdown-menu a:hover {
- background-color: @navbarBackground;
- }
- // Dropdowns in the navbar
- .navbar .dropdown-menu {
- position: static;
- top: auto;
- left: auto;
- float: none;
- display: block;
- max-width: none;
- margin: 0 15px;
- padding: 0;
- background-color: transparent;
- border: none;
- .border-radius(0);
- .box-shadow(none);
- }
- .navbar .dropdown-menu:before,
- .navbar .dropdown-menu:after {
- display: none;
- }
- .navbar .dropdown-menu .divider {
- display: none;
- }
- // Forms in navbar
- .navbar-form,
- .navbar-search {
- float: none;
- padding: (@baseLineHeight / 2) 15px;
- margin: (@baseLineHeight / 2) 0;
- border-top: 1px solid @navbarBackground;
- border-bottom: 1px solid @navbarBackground;
- @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);
- .box-shadow(@shadow);
- }
- // Pull right (secondary) nav content
- .navbar .nav.pull-right {
- float: none;
- margin-left: 0;
- }
- // Static navbar
- .navbar-static .navbar-inner {
- padding-left: 10px;
- padding-right: 10px;
- }
- // Navbar button
- .btn-navbar {
- display: block;
- }
-
- // Hide everything in the navbar save .brand and toggle button */
- .nav-collapse {
- overflow: hidden;
- height: 0;
- }
-}
-
-
-
-// DEFAULT DESKTOP
-// ---------------
-
-@media (min-width: 980px) {
- .nav-collapse.collapse {
- height: auto !important;
- }
-}
-
-
-
-// LARGE DESKTOP & UP
-// ------------------
-
-@media (min-width: 1200px) {
-
- // Fixed grid
- #gridSystem > .generate(12, 70px, 30px);
-
- // Fluid grid
- #fluidGridSystem > .generate(12, 5.982905983%, 2.564102564%);
-
- // Input grid
- #inputGridSystem > .generate(12, 70px, 30px);
-
- // Thumbnails
- .thumbnails {
- margin-left: -30px;
- }
- .thumbnails > li {
- margin-left: 30px;
- }
-
-}
diff --git a/openstack_dashboard/static/bootstrap/less/scaffolding.less b/openstack_dashboard/static/bootstrap/less/scaffolding.less
deleted file mode 100644
index 47ce5381..00000000
--- a/openstack_dashboard/static/bootstrap/less/scaffolding.less
+++ /dev/null
@@ -1,29 +0,0 @@
-// Scaffolding
-// Basic and global styles for generating a grid system, structural layout, and page templates
-// -------------------------------------------------------------------------------------------
-
-
-// STRUCTURAL LAYOUT
-// -----------------
-
-body {
- margin: 0;
- font-family: @baseFontFamily;
- font-size: @baseFontSize;
- line-height: @baseLineHeight;
- color: @textColor;
- background-color: @white;
-}
-
-
-// LINKS
-// -----
-
-a {
- color: @linkColor;
- text-decoration: none;
-}
-a:hover {
- color: @linkColorHover;
- text-decoration: underline;
-}
diff --git a/openstack_dashboard/static/bootstrap/less/sprites.less b/openstack_dashboard/static/bootstrap/less/sprites.less
deleted file mode 100644
index a7741661..00000000
--- a/openstack_dashboard/static/bootstrap/less/sprites.less
+++ /dev/null
@@ -1,158 +0,0 @@
-// SPRITES
-// Glyphs and icons for buttons, nav, and more
-// -------------------------------------------
-
-
-// ICONS
-// -----
-
-// All icons receive the styles of the <i> tag with a base class
-// of .i and are then given a unique class to add width, height,
-// and background-position. Your resulting HTML will look like
-// <i class="icon-inbox"></i>.
-
-// For the white version of the icons, just add the .icon-white class:
-// <i class="icon-inbox icon-white"></i>
-
-[class^="icon-"],
-[class*=" icon-"] {
- display: inline-block;
- width: 14px;
- height: 14px;
- line-height: 14px;
- vertical-align: text-top;
- background-image: url(@iconSpritePath);
- background-position: 14px 14px;
- background-repeat: no-repeat;
-
- .ie7-restore-right-whitespace();
-}
-.icon-white {
- background-image: url(@iconWhiteSpritePath);
-}
-
-.icon-glass { background-position: 0 0; }
-.icon-music { background-position: -24px 0; }
-.icon-search { background-position: -48px 0; }
-.icon-envelope { background-position: -72px 0; }
-.icon-heart { background-position: -96px 0; }
-.icon-star { background-position: -120px 0; }
-.icon-star-empty { background-position: -144px 0; }
-.icon-user { background-position: -168px 0; }
-.icon-film { background-position: -192px 0; }
-.icon-th-large { background-position: -216px 0; }
-.icon-th { background-position: -240px 0; }
-.icon-th-list { background-position: -264px 0; }
-.icon-ok { background-position: -288px 0; }
-.icon-remove { background-position: -312px 0; }
-.icon-zoom-in { background-position: -336px 0; }
-.icon-zoom-out { background-position: -360px 0; }
-.icon-off { background-position: -384px 0; }
-.icon-signal { background-position: -408px 0; }
-.icon-cog { background-position: -432px 0; }
-.icon-trash { background-position: -456px 0; }
-
-.icon-home { background-position: 0 -24px; }
-.icon-file { background-position: -24px -24px; }
-.icon-time { background-position: -48px -24px; }
-.icon-road { background-position: -72px -24px; }
-.icon-download-alt { background-position: -96px -24px; }
-.icon-download { background-position: -120px -24px; }
-.icon-upload { background-position: -144px -24px; }
-.icon-inbox { background-position: -168px -24px; }
-.icon-play-circle { background-position: -192px -24px; }
-.icon-repeat { background-position: -216px -24px; }
-.icon-refresh { background-position: -240px -24px; }
-.icon-list-alt { background-position: -264px -24px; }
-.icon-lock { background-position: -287px -24px; } // 1px off
-.icon-flag { background-position: -312px -24px; }
-.icon-headphones { background-position: -336px -24px; }
-.icon-volume-off { background-position: -360px -24px; }
-.icon-volume-down { background-position: -384px -24px; }
-.icon-volume-up { background-position: -408px -24px; }
-.icon-qrcode { background-position: -432px -24px; }
-.icon-barcode { background-position: -456px -24px; }
-
-.icon-tag { background-position: 0 -48px; }
-.icon-tags { background-position: -25px -48px; } // 1px off
-.icon-book { background-position: -48px -48px; }
-.icon-bookmark { background-position: -72px -48px; }
-.icon-print { background-position: -96px -48px; }
-.icon-camera { background-position: -120px -48px; }
-.icon-font { background-position: -144px -48px; }
-.icon-bold { background-position: -167px -48px; } // 1px off
-.icon-italic { background-position: -192px -48px; }
-.icon-text-height { background-position: -216px -48px; }
-.icon-text-width { background-position: -240px -48px; }
-.icon-align-left { background-position: -264px -48px; }
-.icon-align-center { background-position: -288px -48px; }
-.icon-align-right { background-position: -312px -48px; }
-.icon-align-justify { background-position: -336px -48px; }
-.icon-list { background-position: -360px -48px; }
-.icon-indent-left { background-position: -384px -48px; }
-.icon-indent-right { background-position: -408px -48px; }
-.icon-facetime-video { background-position: -432px -48px; }
-.icon-picture { background-position: -456px -48px; }
-
-.icon-pencil { background-position: 0 -72px; }
-.icon-map-marker { background-position: -24px -72px; }
-.icon-adjust { background-position: -48px -72px; }
-.icon-tint { background-position: -72px -72px; }
-.icon-edit { background-position: -96px -72px; }
-.icon-share { background-position: -120px -72px; }
-.icon-check { background-position: -144px -72px; }
-.icon-move { background-position: -168px -72px; }
-.icon-step-backward { background-position: -192px -72px; }
-.icon-fast-backward { background-position: -216px -72px; }
-.icon-backward { background-position: -240px -72px; }
-.icon-play { background-position: -264px -72px; }
-.icon-pause { background-position: -288px -72px; }
-.icon-stop { background-position: -312px -72px; }
-.icon-forward { background-position: -336px -72px; }
-.icon-fast-forward { background-position: -360px -72px; }
-.icon-step-forward { background-position: -384px -72px; }
-.icon-eject { background-position: -408px -72px; }
-.icon-chevron-left { background-position: -432px -72px; }
-.icon-chevron-right { background-position: -456px -72px; }
-
-.icon-plus-sign { background-position: 0 -96px; }
-.icon-minus-sign { background-position: -24px -96px; }
-.icon-remove-sign { background-position: -48px -96px; }
-.icon-ok-sign { background-position: -72px -96px; }
-.icon-question-sign { background-position: -96px -96px; }
-.icon-info-sign { background-position: -120px -96px; }
-.icon-screenshot { background-position: -144px -96px; }
-.icon-remove-circle { background-position: -168px -96px; }
-.icon-ok-circle { background-position: -192px -96px; }
-.icon-ban-circle { background-position: -216px -96px; }
-.icon-arrow-left { background-position: -240px -96px; }
-.icon-arrow-right { background-position: -264px -96px; }
-.icon-arrow-up { background-position: -289px -96px; } // 1px off
-.icon-arrow-down { background-position: -312px -96px; }
-.icon-share-alt { background-position: -336px -96px; }
-.icon-resize-full { background-position: -360px -96px; }
-.icon-resize-small { background-position: -384px -96px; }
-.icon-plus { background-position: -408px -96px; }
-.icon-minus { background-position: -433px -96px; }
-.icon-asterisk { background-position: -456px -96px; }
-
-.icon-exclamation-sign { background-position: 0 -120px; }
-.icon-gift { background-position: -24px -120px; }
-.icon-leaf { background-position: -48px -120px; }
-.icon-fire { background-position: -72px -120px; }
-.icon-eye-open { background-position: -96px -120px; }
-.icon-eye-close { background-position: -120px -120px; }
-.icon-warning-sign { background-position: -144px -120px; }
-.icon-plane { background-position: -168px -120px; }
-.icon-calendar { background-position: -192px -120px; }
-.icon-random { background-position: -216px -120px; }
-.icon-comment { background-position: -240px -120px; }
-.icon-magnet { background-position: -264px -120px; }
-.icon-chevron-up { background-position: -288px -120px; }
-.icon-chevron-down { background-position: -313px -119px; } // 1px off
-.icon-retweet { background-position: -336px -120px; }
-.icon-shopping-cart { background-position: -360px -120px; }
-.icon-folder-close { background-position: -384px -120px; }
-.icon-folder-open { background-position: -408px -120px; }
-.icon-resize-vertical { background-position: -432px -119px; }
-.icon-resize-horizontal { background-position: -456px -118px; }
diff --git a/openstack_dashboard/static/bootstrap/less/tables.less b/openstack_dashboard/static/bootstrap/less/tables.less
deleted file mode 100644
index 3a4066d7..00000000
--- a/openstack_dashboard/static/bootstrap/less/tables.less
+++ /dev/null
@@ -1,150 +0,0 @@
-//
-// Tables.less
-// Tables for, you guessed it, tabular data
-// ----------------------------------------
-
-
-// BASE TABLES
-// -----------------
-
-table {
- max-width: 100%;
- border-collapse: collapse;
- border-spacing: 0;
-}
-
-// BASELINE STYLES
-// ---------------
-
-.table {
- width: 100%;
- margin-bottom: @baseLineHeight;
- // Cells
- th,
- td {
- padding: 8px;
- line-height: @baseLineHeight;
- text-align: left;
- vertical-align: top;
- border-top: 1px solid #ddd;
- }
- th {
- font-weight: bold;
- }
- // Bottom align for column headings
- thead th {
- vertical-align: bottom;
- }
- // Remove top border from thead by default
- thead:first-child tr th,
- thead:first-child tr td {
- border-top: 0;
- }
- // Account for multiple tbody instances
- tbody + tbody {
- border-top: 2px solid #ddd;
- }
-}
-
-
-
-// CONDENSED TABLE W/ HALF PADDING
-// -------------------------------
-
-.table-condensed {
- th,
- td {
- padding: 4px 5px;
- }
-}
-
-
-// BORDERED VERSION
-// ----------------
-
-.table-bordered {
- border: 1px solid #ddd;
- border-collapse: separate; // Done so we can round those corners!
- *border-collapse: collapsed; // IE7 can't round corners anyway
- .border-radius(4px);
- th + th,
- td + td,
- th + td,
- td + th {
- border-left: 1px solid #ddd;
- }
- // Prevent a double border
- thead:first-child tr:first-child th,
- tbody:first-child tr:first-child th,
- tbody:first-child tr:first-child td {
- border-top: 0;
- }
- // For first th or td in the first row in the first thead or tbody
- thead:first-child tr:first-child th:first-child,
- tbody:first-child tr:first-child td:first-child {
- .border-radius(4px 0 0 0);
- }
- thead:first-child tr:first-child th:last-child,
- tbody:first-child tr:first-child td:last-child {
- .border-radius(0 4px 0 0);
- }
- // For first th or td in the first row in the first thead or tbody
- thead:last-child tr:last-child th:first-child,
- tbody:last-child tr:last-child td:first-child {
- .border-radius(0 0 0 4px);
- }
- thead:last-child tr:last-child th:last-child,
- tbody:last-child tr:last-child td:last-child {
- .border-radius(0 0 4px 0);
- }
-}
-
-
-// ZEBRA-STRIPING
-// --------------
-
-// Default zebra-stripe styles (alternating gray and transparent backgrounds)
-.table-striped {
- tbody {
- tr:nth-child(odd) td,
- tr:nth-child(odd) th {
- background-color: #f9f9f9;
- }
- }
-}
-
-
-// HOVER EFFECT
-// ------------
-// Placed here since it has to come after the potential zebra striping
-.table {
- tbody tr:hover td,
- tbody tr:hover th {
- background-color: #f5f5f5;
- }
-}
-
-
-// TABLE CELL SIZING
-// -----------------
-
-// Change the columns
-.tableColumns(@columnSpan: 1) {
- float: none;
- width: ((@gridColumnWidth) * @columnSpan) + (@gridGutterWidth * (@columnSpan - 1)) - 16;
- margin-left: 0;
-}
-table {
- .span1 { .tableColumns(1); }
- .span2 { .tableColumns(2); }
- .span3 { .tableColumns(3); }
- .span4 { .tableColumns(4); }
- .span5 { .tableColumns(5); }
- .span6 { .tableColumns(6); }
- .span7 { .tableColumns(7); }
- .span8 { .tableColumns(8); }
- .span9 { .tableColumns(9); }
- .span10 { .tableColumns(10); }
- .span11 { .tableColumns(11); }
- .span12 { .tableColumns(12); }
-}
diff --git a/openstack_dashboard/static/bootstrap/less/thumbnails.less b/openstack_dashboard/static/bootstrap/less/thumbnails.less
deleted file mode 100644
index 3a12d4e5..00000000
--- a/openstack_dashboard/static/bootstrap/less/thumbnails.less
+++ /dev/null
@@ -1,35 +0,0 @@
-// THUMBNAILS
-// ----------
-
-.thumbnails {
- margin-left: -@gridGutterWidth;
- list-style: none;
- .clearfix();
-}
-.thumbnails > li {
- float: left;
- margin: 0 0 @baseLineHeight @gridGutterWidth;
-}
-.thumbnail {
- display: block;
- padding: 4px;
- line-height: 1;
- border: 1px solid #ddd;
- .border-radius(4px);
- .box-shadow(0 1px 1px rgba(0,0,0,.075));
-}
-// Add a hover state for linked versions only
-a.thumbnail:hover {
- border-color: @linkColor;
- .box-shadow(0 1px 4px rgba(0,105,214,.25));
-}
-// Images and captions
-.thumbnail > img {
- display: block;
- max-width: 100%;
- margin-left: auto;
- margin-right: auto;
-}
-.thumbnail .caption {
- padding: 9px;
-}
diff --git a/openstack_dashboard/static/bootstrap/less/tooltip.less b/openstack_dashboard/static/bootstrap/less/tooltip.less
deleted file mode 100644
index 5111a193..00000000
--- a/openstack_dashboard/static/bootstrap/less/tooltip.less
+++ /dev/null
@@ -1,35 +0,0 @@
-// TOOLTIP
-// ------=
-
-.tooltip {
- position: absolute;
- z-index: @zindexTooltip;
- display: block;
- visibility: visible;
- padding: 5px;
- font-size: 11px;
- .opacity(0);
- &.in { .opacity(80); }
- &.top { margin-top: -2px; }
- &.right { margin-left: 2px; }
- &.bottom { margin-top: 2px; }
- &.left { margin-left: -2px; }
- &.top .tooltip-arrow { #popoverArrow > .top(); }
- &.left .tooltip-arrow { #popoverArrow > .left(); }
- &.bottom .tooltip-arrow { #popoverArrow > .bottom(); }
- &.right .tooltip-arrow { #popoverArrow > .right(); }
-}
-.tooltip-inner {
- max-width: 200px;
- padding: 3px 8px;
- color: @white;
- text-align: center;
- text-decoration: none;
- background-color: @black;
- .border-radius(4px);
-}
-.tooltip-arrow {
- position: absolute;
- width: 0;
- height: 0;
-}
diff --git a/openstack_dashboard/static/bootstrap/less/type.less b/openstack_dashboard/static/bootstrap/less/type.less
deleted file mode 100644
index df52f781..00000000
--- a/openstack_dashboard/static/bootstrap/less/type.less
+++ /dev/null
@@ -1,222 +0,0 @@
-// Typography.less
-// Headings, body text, lists, code, and more for a versatile and durable typography system
-// ----------------------------------------------------------------------------------------
-
-
-// BODY TEXT
-// ---------
-
-p {
- margin: 0 0 @baseLineHeight / 2;
- font-family: @baseFontFamily;
- font-size: @baseFontSize;
- line-height: @baseLineHeight;
- small {
- font-size: @baseFontSize - 2;
- color: @grayLight;
- }
-}
-.lead {
- margin-bottom: @baseLineHeight;
- font-size: 20px;
- font-weight: 200;
- line-height: @baseLineHeight * 1.5;
-}
-
-// HEADINGS
-// --------
-
-h1, h2, h3, h4, h5, h6 {
- margin: 0;
- font-weight: bold;
- color: @grayDark;
- text-rendering: optimizelegibility; // Fix the character spacing for headings
- small {
- font-weight: normal;
- color: @grayLight;
- }
-}
-h1 {
- font-size: 30px;
- line-height: @baseLineHeight * 2;
- small {
- font-size: 18px;
- }
-}
-h2 {
- font-size: 24px;
- line-height: @baseLineHeight * 2;
- small {
- font-size: 18px;
- }
-}
-h3 {
- line-height: @baseLineHeight * 1.5;
- font-size: 18px;
- small {
- font-size: 14px;
- }
-}
-h4, h5, h6 {
- line-height: @baseLineHeight;
-}
-h4 {
- font-size: 14px;
- small {
- font-size: 12px;
- }
-}
-h5 {
- font-size: 12px;
-}
-h6 {
- font-size: 11px;
- color: @grayLight;
- text-transform: uppercase;
-}
-
-// Page header
-.page-header {
- padding-bottom: @baseLineHeight - 1;
- margin: @baseLineHeight 0;
- border-bottom: 1px solid @grayLighter;
-}
-.page-header h1 {
- line-height: 1;
-}
-
-
-
-// LISTS
-// -----
-
-// Unordered and Ordered lists
-ul, ol {
- padding: 0;
- margin: 0 0 @baseLineHeight / 2 25px;
-}
-ul ul,
-ul ol,
-ol ol,
-ol ul {
- margin-bottom: 0;
-}
-ul {
- list-style: disc;
-}
-ol {
- list-style: decimal;
-}
-li {
- line-height: @baseLineHeight;
-}
-ul.unstyled,
-ol.unstyled {
- margin-left: 0;
- list-style: none;
-}
-table ul {
- margin: 0;
- list-style-type: none;
-}
-
-// Description Lists
-dl {
- margin-bottom: @baseLineHeight;
-}
-dt,
-dd {
- line-height: @baseLineHeight;
-}
-dt {
- font-weight: bold;
-}
-dd {
- margin-left: @baseLineHeight / 2;
-}
-
-// MISC
-// ----
-
-// Horizontal rules
-hr {
- margin: @baseLineHeight 0;
- border: 0;
- border-top: 1px solid @hrBorder;
- border-bottom: 1px solid @white;
-}
-
-// Emphasis
-strong {
- font-weight: bold;
-}
-em {
- font-style: italic;
-}
-.muted {
- color: @grayLight;
-}
-
-// Abbreviations and acronyms
-abbr {
- font-size: 90%;
- text-transform: uppercase;
- border-bottom: 1px dotted #ddd;
- cursor: help;
-}
-
-// Blockquotes
-blockquote {
- padding: 0 0 0 15px;
- margin: 0 0 @baseLineHeight;
- border-left: 5px solid @grayLighter;
- p {
- margin-bottom: 0;
- #font > .shorthand(16px,300,@baseLineHeight * 1.25);
- }
- small {
- display: block;
- line-height: @baseLineHeight;
- color: @grayLight;
- &:before {
- content: '\2014 \00A0';
- }
- }
-
- // Float right with text-align: right
- &.pull-right {
- float: right;
- padding-left: 0;
- padding-right: 15px;
- border-left: 0;
- border-right: 5px solid @grayLighter;
- p,
- small {
- text-align: right;
- }
- }
-}
-
-// Quotes
-q:before,
-q:after,
-blockquote:before,
-blockquote:after {
- content: "";
-}
-
-// Addresses
-address {
- display: block;
- margin-bottom: @baseLineHeight;
- line-height: @baseLineHeight;
- font-style: normal;
-}
-
-// Misc
-small {
- font-size: 100%;
-}
-cite {
- font-style: normal;
-}
diff --git a/openstack_dashboard/static/bootstrap/less/utilities.less b/openstack_dashboard/static/bootstrap/less/utilities.less
deleted file mode 100644
index d60d2203..00000000
--- a/openstack_dashboard/static/bootstrap/less/utilities.less
+++ /dev/null
@@ -1,23 +0,0 @@
-// UTILITY CLASSES
-// ---------------
-
-// Quick floats
-.pull-right {
- float: right;
-}
-.pull-left {
- float: left;
-}
-
-// Toggling content
-.hide {
- display: none;
-}
-.show {
- display: block;
-}
-
-// Visibility
-.invisible {
- visibility: hidden;
-}
diff --git a/openstack_dashboard/static/bootstrap/less/variables.less b/openstack_dashboard/static/bootstrap/less/variables.less
deleted file mode 100644
index 9262ff3b..00000000
--- a/openstack_dashboard/static/bootstrap/less/variables.less
+++ /dev/null
@@ -1,107 +0,0 @@
-// Variables.less
-// Variables to customize the look and feel of Bootstrap
-// -----------------------------------------------------
-
-
-
-// GLOBAL VALUES
-// --------------------------------------------------
-
-// Links
-@linkColor: #08c;
-@linkColorHover: darken(@linkColor, 15%);
-
-// Grays
-@black: #000;
-@grayDarker: #222;
-@grayDark: #333;
-@gray: #555;
-@grayLight: #999;
-@grayLighter: #eee;
-@white: #fff;
-
-// Accent colors
-@blue: #049cdb;
-@blueDark: #0064cd;
-@green: #46a546;
-@red: #9d261d;
-@yellow: #ffc40d;
-@orange: #f89406;
-@pink: #c3325f;
-@purple: #7a43b6;
-
-// Typography
-@baseFontSize: 13px;
-@baseFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif;
-@baseLineHeight: 18px;
-@textColor: @grayDark;
-
-// Buttons
-@primaryButtonBackground: @linkColor;
-
-
-
-// COMPONENT VARIABLES
-// --------------------------------------------------
-
-// Z-index master list
-// Used for a bird's eye view of components dependent on the z-axis
-// Try to avoid customizing these :)
-@zindexDropdown: 1000;
-@zindexPopover: 1010;
-@zindexTooltip: 1020;
-@zindexFixedNavbar: 1030;
-@zindexModalBackdrop: 1040;
-@zindexModal: 1050;
-
-// Sprite icons path
-@iconSpritePath: "/static/bootstrap/img/glyphicons-halflings.png";
-@iconWhiteSpritePath: "/static/bootstrap/img/glyphicons-halflings-white.png";
-
-// Input placeholder text color
-@placeholderText: @grayLight;
-
-// Hr border color
-@hrBorder: @grayLighter;
-
-// Navbar
-@navbarHeight: 40px;
-@navbarBackground: @grayDarker;
-@navbarBackgroundHighlight: @grayDark;
-@navbarLinkBackgroundHover: transparent;
-
-@navbarText: @grayLight;
-@navbarLinkColor: @grayLight;
-@navbarLinkColorHover: @white;
-
-// Form states and alerts
-@warningText: #c09853;
-@warningBackground: #fcf8e3;
-@warningBorder: darken(spin(@warningBackground, -10), 3%);
-
-@errorText: #b94a48;
-@errorBackground: #f2dede;
-@errorBorder: darken(spin(@errorBackground, -10), 3%);
-
-@successText: #468847;
-@successBackground: #dff0d8;
-@successBorder: darken(spin(@successBackground, -10), 5%);
-
-@infoText: #3a87ad;
-@infoBackground: #d9edf7;
-@infoBorder: darken(spin(@infoBackground, -10), 7%);
-
-
-
-// GRID
-// --------------------------------------------------
-
-// Default 940px grid
-@gridColumns: 12;
-@gridColumnWidth: 60px;
-@gridGutterWidth: 20px;
-@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1));
-
-// Fluid grid
-@fluidGridColumnWidth: 6.382978723%;
-@fluidGridGutterWidth: 2.127659574%; \ No newline at end of file
diff --git a/openstack_dashboard/static/bootstrap/less/wells.less b/openstack_dashboard/static/bootstrap/less/wells.less
deleted file mode 100644
index 244b8ca1..00000000
--- a/openstack_dashboard/static/bootstrap/less/wells.less
+++ /dev/null
@@ -1,17 +0,0 @@
-// WELLS
-// -----
-
-.well {
- min-height: 20px;
- padding: 19px;
- margin-bottom: 20px;
- background-color: #f5f5f5;
- border: 1px solid #eee;
- border: 1px solid rgba(0,0,0,.05);
- .border-radius(4px);
- .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));
- blockquote {
- border-color: #ddd;
- border-color: rgba(0,0,0,.15);
- }
-}
diff --git a/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.eot b/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.eot
deleted file mode 100644
index 9bebfd6b..00000000
--- a/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.eot
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.svg b/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.svg
deleted file mode 100644
index 1a849bfb..00000000
--- a/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.svg
+++ /dev/null
@@ -1,244 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
-<svg xmlns="http://www.w3.org/2000/svg">
-<metadata>
-This is a custom SVG webfont generated by Fontspring.
-</metadata>
-<defs>
-<font id="webfont3JLVF59W" horiz-adv-x="1028" >
-<font-face units-per-em="2048" ascent="1546" descent="-502" />
-<missing-glyph horiz-adv-x="509" />
-<glyph unicode=" " horiz-adv-x="509" />
-<glyph unicode="&#x09;" horiz-adv-x="509" />
-<glyph unicode="&#xa0;" horiz-adv-x="509" />
-<glyph unicode="!" horiz-adv-x="587" d="M186 1448l11 12l188 25l12 -8l-39 -1086l-10 -10h-108l-11 10zM193 10v187l10 10h182l10 -10v-187l-10 -10h-182z" />
-<glyph unicode="&#x22;" horiz-adv-x="708" d="M106 1372l11 10h159l11 -10l-21 -346l-10 -10h-117l-10 10zM422 1372l10 10h160l10 -10l-20 -346l-11 -10h-116l-11 10z" />
-<glyph unicode="#" horiz-adv-x="1372" d="M92 377v121l10 10h236l68 362h-203l-10 11v120l10 11h229l66 350l12 12l131 21l12 -11l-69 -372h309l65 350l13 12l131 21l12 -11l-70 -372h248l8 -11l-34 -120l-15 -11h-233l-68 -362h242l8 -10l-35 -121l-14 -10h-227l-66 -357l-12 -10h-131l-8 10l65 357h-309 l-66 -357l-12 -10h-131l-8 10l65 357h-209zM489 508h310l67 362h-309z" />
-<glyph unicode="$" horiz-adv-x="1005" d="M104 106l70 109l16 2q96 -78 259 -84v363q-74 25 -118 45t-96.5 56t-77 88t-24.5 122q0 121 90 197.5t226 97.5v137l10 12l98 15l10 -9v-151q74 -4 144.5 -22.5t105.5 -33t47 -24.5l2 -10l-63 -113l-15 -2q-78 51 -221 57v-335q74 -25 121 -46.5t100.5 -59.5t80 -94 t26.5 -130q0 -137 -94 -209t-234 -90v-144l-10 -10h-98l-10 10v136q-195 8 -340 110zM297 811q0 -53 39 -86t113 -61v288q-152 -26 -152 -141zM567 139q164 23 164 154q0 57 -42 94t-122 68v-316z" />
-<glyph unicode="%" horiz-adv-x="1443" d="M119 967v209q0 104 67.5 162.5t176 58.5t175 -58.5t66.5 -162.5v-209q0 -104 -66.5 -161.5t-175 -57.5t-176 57.5t-67.5 161.5zM123 10l1032 1381l14 4l127 -39l4 -10l-1003 -1342l-12 -4h-158zM240 989q0 -123 122 -123q121 0 121 123v168q0 119 -121 119 q-123 0 -122 -119v-168zM842 199v207q0 106 67.5 163.5t175.5 57.5q111 0 178.5 -57.5t67.5 -163.5v-207q0 -104 -68.5 -164t-177 -60t-176 60t-67.5 164zM963 215q0 -119 122 -119q121 0 121 119v170q0 121 -121 121q-123 0 -122 -121v-170z" />
-<glyph unicode="&#x26;" horiz-adv-x="1224" d="M117 410q0 121 56 210t159 107q-82 37 -131 116t-49 181q0 188 123.5 273t326.5 85h131l8 -10l-22 -127l-12 -10h-105q-287 0 -287 -209q0 -119 70 -168t227 -49h168l19 207l10 12l117 16l10 -8v-227h207l10 -10l-39 -127l-14 -10h-164v-629l-10 -13q-145 -45 -338 -45 q-197 0 -334 108t-137 327zM281 412q0 -141 93 -215t218 -74l180 22v517h-160q-156 0 -243.5 -68.5t-87.5 -181.5z" />
-<glyph unicode="'" horiz-adv-x="393" d="M106 1372l11 10h159l11 -10l-21 -346l-10 -10h-117l-10 10z" />
-<glyph unicode="(" horiz-adv-x="577" d="M131 571.5q0 180.5 28.5 333t69.5 240.5t82 151.5t70 87.5l29 23h14l82 -90l-2 -14q-8 -8 -22.5 -25.5t-50.5 -81t-63.5 -140.5t-50 -207t-22.5 -277.5t21.5 -277.5t53 -210t62.5 -138.5t51 -82.5l23 -25l-2 -14l-80 -88l-14 -2q-12 8 -31 24.5t-67 84t-85 153.5 t-66.5 240.5t-29.5 335z" />
-<glyph unicode=")" horiz-adv-x="577" d="M72 -162q8 8 22.5 25.5t51 81t64.5 140.5t50.5 208t22.5 278.5t-21.5 276.5t-52.5 209t-61.5 138t-53.5 83l-20 25l-2 14l82 90h14q12 -8 30.5 -24.5t66.5 -85t85 -153.5t66.5 -238.5t29.5 -334t-28.5 -334t-69.5 -242.5t-82 -151.5t-69 -85.5l-29 -24l-14 2l-80 88z" />
-<glyph unicode="*" horiz-adv-x="1110" d="M102 1012l43 118l13 7l213 -123q47 -27 69 -27q6 0 19 4v-16q-47 -80 -125 -80q-53 0 -109 33l-119 69zM197 684l2 14l213 123q55 33 63 66l12 -8q25 -41 25 -84q0 -82 -100 -142l-119 -69l-14 4zM371 1227v137l10 12l125 23l10 -8v-246q0 -68 25 -88l-15 -8 q-155 0 -155 178zM573 848l15 8q156 0 155 -178v-137l-10 -13l-125 -22l-10 8v246q0 68 -25 88zM602 1110q0 82 100 141l119 70l15 -4l82 -96l-3 -15l-213 -123q-55 -33 -63 -65l-12 8q-25 41 -25 84zM655 913v17q47 80 125 80q51 0 109 -33l119 -70l4 -14l-43 -119l-13 -6 l-213 123q-45 25 -69 24q-13 0 -19 -2z" />
-<glyph unicode="+" horiz-adv-x="1126" d="M193 465v129l10 10h264v293l10 12l144 21l10 -8v-318h297l8 -10l-33 -129l-12 -10h-260v-330l-10 -10h-144l-10 10v330h-264z" />
-<glyph unicode="," horiz-adv-x="505" d="M66 -225l86 428l12 10h215l6 -10l-217 -459l-14 -8l-80 24z" />
-<glyph unicode="-" horiz-adv-x="870" d="M170 459v143l10 10h527l8 -10l-37 -143l-12 -10h-486z" />
-<glyph unicode="." horiz-adv-x="483" d="M137 10v193l10 10h189l10 -10v-193l-10 -10h-189z" />
-<glyph unicode="/" horiz-adv-x="708" d="M72 -143l399 1505l10 12l144 21l12 -9l-408 -1527l-12 -13h-139z" />
-<glyph unicode="0" horiz-adv-x="1167" d="M137 373v327q0 199 130 298.5t316.5 99.5t316.5 -99.5t130 -298.5v-327q0 -199 -130 -298.5t-316.5 -99.5t-316.5 99.5t-130 298.5zM301 408q0 -139 78 -212t205 -73t204.5 72.5t77.5 212.5v258q0 139 -77.5 211.5t-204.5 72.5t-205 -72.5t-78 -211.5v-258z" />
-<glyph unicode="1" horiz-adv-x="897" d="M84 10v127l10 10h287v779h-195l-12 10l-37 127l8 10h390l10 -10v-916h299l8 -10l-37 -127l-12 -10h-709z" />
-<glyph unicode="2" horiz-adv-x="1054" d="M84 872q6 8 16.5 23.5t49 54.5t84 69t122 54.5t160.5 24.5q170 0 279.5 -91.5t109.5 -258.5q0 -92 -40 -183.5t-91 -153t-113.5 -114.5t-97.5 -74.5t-49 -29.5l-86 -46h518l8 -10l-34 -127l-13 -10h-739l-10 10l-19 90q84 45 171 104.5t189.5 144.5t167 188.5t64.5 200 t-61.5 152.5t-169.5 56q-162 0 -277 -143l-14 -21h-14l-109 74z" />
-<glyph unicode="3" horiz-adv-x="1067" d="M49 -88l2 16l105 74h14q4 -8 12 -19.5t39 -42t64.5 -54t89 -43t114.5 -19.5q119 0 205 69.5t86 186.5v29q0 115 -89 178t-251 63h-90l-8 10l35 127l12 11h51q305 0 305 225q0 115 -74.5 171t-191.5 56q-170 0 -276 -131l-13 -18h-16l-102 73l-2 15q4 8 14 22.5t47 50 t81 63.5t115.5 50.5t151.5 22.5q193 0 311.5 -99.5t118.5 -275.5q0 -94 -50 -181t-134 -122q100 -33 159.5 -111t59.5 -172v-78q0 -174 -133 -278.5t-315 -104.5q-90 0 -170 25t-128 59.5t-84 68.5t-51 58z" />
-<glyph unicode="4" horiz-adv-x="1099" d="M49 172l637 883l12 8l119 20l10 -8v-866h254l9 -10l-37 -127l-13 -11h-213v-360l-10 -12l-143 -21l-10 8v385h-574l-10 11zM260 209h404v493l4 72l-35 -61l-342 -467z" />
-<glyph unicode="5" horiz-adv-x="999" d="M0 -94l2 16l104 74h15q4 -8 12 -19.5t39 -42t64.5 -54t90 -43t117.5 -19.5q115 0 202 69.5t87 184.5v61q0 115 -87 183.5t-202 68.5q-137 0 -237 -55h-10l-64 88v645l12 10h678l8 -10l-36 -127l-13 -10h-485v-410q74 16 152 16q180 0 314 -102t134 -276v-105 q0 -172 -134 -275.5t-314 -103.5q-90 0 -169 24.5t-128.5 58.5t-85 69t-50.5 59z" />
-<glyph unicode="6" horiz-adv-x="1155" d="M162 373v628q0 174 133 288t321 114q80 0 152 -23.5t116 -56.5t77.5 -65.5t48.5 -57.5l14 -22v-15l-106 -76h-17q-2 4 -13 20.5t-37 42.5t-57.5 48.5t-78.5 39.5t-99 17q-121 0 -205.5 -68.5t-84.5 -215.5v-154l-13 -96q4 10 11.5 24.5t31 39t55 44t86 35t119.5 15.5 q178 0 304.5 -99.5t126.5 -302.5v-104q0 -201 -128 -299.5t-314.5 -98.5t-314.5 98.5t-128 299.5zM326 408q0 -139 77.5 -212t200.5 -73q125 0 202 71.5t77 213.5v32q0 139 -77 213t-198 74q-180 0 -282 -65v-254z" />
-<glyph unicode="7" horiz-adv-x="931" d="M35 1063l6 10h809l8 -10l19 -80l-555 -1300l-13 -7l-137 35l-6 10l512 1205h-590l-12 8z" />
-<glyph unicode="8" horiz-adv-x="1134" d="M125 373q0 109 58.5 205t156.5 129q-78 31 -131 115.5t-53 187.5q0 190 110.5 291.5t302.5 101.5q188 0 298 -101.5t110 -291.5q0 -102 -52.5 -188.5t-129.5 -114.5q98 -33 155.5 -129.5t57.5 -204.5q0 -199 -126 -298.5t-312.5 -99.5t-315.5 99.5t-129 298.5zM289 375 q0 -119 78.5 -185.5t201.5 -66.5q121 0 198 67.5t77 184.5q0 115 -78 186.5t-197 71.5q-121 0 -200.5 -71.5t-79.5 -186.5zM319 1010q0 -109 66 -173.5t184 -64.5q115 0 180.5 64.5t65.5 173.5q0 115 -64.5 180t-181.5 65q-119 0 -184.5 -65t-65.5 -180z" />
-<glyph unicode="9" horiz-adv-x="1157" d="M109 596v104q0 201 128 299.5t314 98.5t314 -98.5t128 -299.5v-622q0 -174 -133 -288t-321 -114q-80 0 -152 24t-116 56.5t-77.5 65.5t-48.5 55l-14 25v14l107 76h16l12 -17.5t36 -41t58.5 -51t78.5 -40t100 -18.5q121 0 205.5 68.5t84.5 216.5v147l13 94q-2 -6 -8.5 -16 t-30 -38t-54 -48.5t-87 -36.5t-123.5 -16q-178 0 -304 99t-126 302zM272 633q0 -139 77 -213t198 -74q180 0 282 66v254q0 139 -77.5 211.5t-200.5 72.5q-125 0 -202 -71.5t-77 -212.5v-33z" />
-<glyph unicode=":" horiz-adv-x="483" d="M137 10v193l10 10h189l10 -10v-193l-10 -10h-189zM137 809v192l10 11h189l10 -11v-192l-10 -10h-189z" />
-<glyph unicode=";" horiz-adv-x="505" d="M66 -225l86 428l12 10h215l6 -10l-217 -459l-14 -8l-80 24zM150 809v192l10 11h188l10 -11v-192l-10 -10h-188z" />
-<glyph unicode="&#x3c;" horiz-adv-x="1126" d="M115 432l32 158l13 12l801 418l10 -8v-146l-10 -14l-678 -352l678 -336l10 -14v-146l-10 -8l-840 420z" />
-<glyph unicode="=" horiz-adv-x="1126" d="M193 285v129l10 10h680l8 -10l-35 -129l-12 -11h-641zM193 645v129l10 10h725l8 -10l-35 -129l-12 -10h-686z" />
-<glyph unicode="&#x3e;" horiz-adv-x="1126" d="M156 2v145l10 15l678 352l-678 336l-10 14v146l10 8l840 -420l6 -16l-33 -158l-12 -12l-801 -418z" />
-<glyph unicode="?" horiz-adv-x="1007" d="M72 1147q0 166 114.5 259t290.5 93t290 -93t114 -259v-215q0 -152 -96.5 -248t-249.5 -113l-7 -180l-10 -10h-121l-10 10v307l10 13l140 22q82 14 127 76.5t45 157.5v145q0 109 -60.5 166t-171.5 57q-113 0 -177 -55t-64 -168l-13 -8l-141 31zM356 10v187l11 10h182 l10 -10v-187l-10 -10h-182z" />
-<glyph unicode="@" horiz-adv-x="1847" d="M133 322v112q0 451 204 710t617 259q389 0 579.5 -180.5t190.5 -554.5v-131q0 -293 -134 -449t-421 -180l-16 8l-84 221q-2 -6 -7 -17t-27.5 -39t-52.5 -49.5t-85 -39t-121 -17.5q-133 0 -204.5 92.5t-71.5 219.5q0 375 128 562t322 187q74 0 162 -19.5t141 -37.5l52 -21 l10 -14l-90 -733l45 -154q147 45 219 165t72 331v94q0 324 -150.5 466t-456.5 142q-330 0 -493.5 -221t-163.5 -614v-80q0 -326 145.5 -468t446.5 -144l6 -15l-27 -127l-12 -8q-356 0 -539.5 185.5t-183.5 558.5zM668 326q0 -203 170 -203q37 0 93 16.5t93 32.5l39 14 l76 656q-78 45 -191 45q-102 0 -191 -134t-89 -427z" />
-<glyph unicode="A" horiz-adv-x="1208" d="M25 10l477 1352l12 10l172 23l12 -9l486 -1376l-6 -10h-164l-13 10l-112 330h-572l-110 -330l-10 -10h-166zM371 496h467l-213 630l-21 88l-20 -88z" />
-<glyph unicode="B" horiz-adv-x="1189" d="M190 10v1362l11 10h372q449 0 449 -350q0 -100 -49 -178t-142 -111q106 -35 167 -124t61 -211q0 -201 -130 -304.5t-319 -103.5h-409zM362 158h226q125 0 211 60.5t86 189.5t-86 190t-211 61h-226v-501zM362 817h213q274 0 275 205q0 117 -75 160t-200 43h-213v-408z" />
-<glyph unicode="C" horiz-adv-x="1284" d="M145 477v418q0 244 145.5 376t391.5 132q170 0 297 -74t182 -209l-6 -12l-137 -57l-14 4q-41 86 -127 135t-195 49q-162 0 -261 -93t-99 -265v-385q0 -176 98 -266.5t262 -90.5q258 0 346 191l14 4l134 -51l6 -13q-51 -145 -180.5 -220t-319.5 -75q-248 0 -392.5 130 t-144.5 372z" />
-<glyph unicode="D" horiz-adv-x="1343" d="M190 10v1362l11 10h458q246 0 392.5 -132t146.5 -376v-372q0 -242 -145.5 -372t-393.5 -130h-458zM362 164h297q164 0 263.5 90t99.5 266v340q0 172 -100.5 265.5t-262.5 93.5h-297v-1055z" />
-<glyph unicode="E" horiz-adv-x="1050" d="M190 10v1362l11 10h710l11 -10v-143l-11 -10h-549v-410h478l8 -10l-37 -144l-12 -10h-437v-481h551l9 -10l-21 -144l-12 -10h-688z" />
-<glyph unicode="F" horiz-adv-x="989" d="M190 10v1362l11 10h690l10 -10v-143l-10 -10h-529v-431h498l8 -10l-37 -143l-12 -10h-457v-615l-10 -10h-151z" />
-<glyph unicode="G" horiz-adv-x="1337" d="M145 477v418q0 244 145.5 376t391.5 132q170 0 297 -74t182 -209l-6 -12l-137 -57l-14 4q-41 86 -127 135t-195 49q-162 0 -261 -93t-99 -265v-385q0 -176 98 -266.5t262 -90.5q166 0 265.5 90t99.5 267v47h-236l-12 10l-21 143l8 11h422l11 -11v-219q0 -244 -142.5 -373 t-394.5 -129q-248 0 -392.5 130t-144.5 372z" />
-<glyph unicode="H" horiz-adv-x="1456" d="M190 10v1352l11 12l151 21l10 -9v-579h730v555l10 12l151 21l11 -9v-1376l-11 -10h-151l-10 10v633h-730v-633l-10 -10h-151z" />
-<glyph unicode="I" horiz-adv-x="555" d="M190 10v1352l11 12l151 21l10 -9v-1376l-10 -10h-151z" />
-<glyph unicode="J" horiz-adv-x="772" d="M8 63l62 127l16 3q70 -53 150 -54q66 0 123 54.5t57 171.5v997l10 12l152 21l10 -9v-1038q0 -170 -94.5 -271.5t-247.5 -101.5q-139 0 -236 74z" />
-<glyph unicode="K" horiz-adv-x="1216" d="M190 10v1352l11 12l151 21l10 -9v-579h97l16 8l426 545l17 10l215 25l8 -11l-488 -589l-59 -60l59 -65l324 -430q63 -86 162 -86q16 0 24 2l8 -11l-22 -139l-12 -10q-12 -2 -37 -2q-154 0 -275 168l-358 485l-16 8h-89v-645l-10 -10h-151z" />
-<glyph unicode="L" horiz-adv-x="970" d="M190 10v1352l11 12l151 21l10 -9v-1222h590l9 -10l-37 -144l-13 -10h-710z" />
-<glyph unicode="M" horiz-adv-x="1656" d="M190 10v1352l11 12l153 21l13 -9l460 -837l449 815l10 12l168 19l10 -9v-1376l-10 -10h-151l-7 10v1082l-51 -113l-332 -594l-12 -10h-147l-13 10l-331 594l-48 113v-1082l-10 -10h-151z" />
-<glyph unicode="N" horiz-adv-x="1447" d="M190 10v1352l11 12l151 21l15 -9l663 -999l53 -98v1073l11 12l151 21l10 -9v-1376l-10 -10h-145l-17 10l-667 1008l-54 98v-1106l-10 -10h-151z" />
-<glyph unicode="O" horiz-adv-x="1368" d="M145 477v418q0 244 146.5 376t392.5 132t392.5 -132t146.5 -376v-418q0 -242 -145.5 -372t-393.5 -130t-393.5 130t-145.5 372zM322 496q0 -176 99 -266.5t263 -90.5t263.5 90t99.5 267v385q0 172 -100.5 265t-262.5 93t-262 -93t-100 -265v-385z" />
-<glyph unicode="P" horiz-adv-x="1134" d="M190 10v1362l11 10h360q209 0 324 -67q172 -100 172 -344q0 -193 -117 -319t-340 -126q-199 0 -248 119l10 -82v-553l-10 -10h-151zM362 715q100 -35 195 -35q145 0 233.5 71.5t88.5 215.5q0 258 -318 258h-199v-510z" />
-<glyph unicode="Q" horiz-adv-x="1368" d="M145 477v418q0 244 146.5 376t392.5 132t392.5 -132t146.5 -376v-418q0 -236 -138.5 -364.5t-371.5 -137.5q-18 -14 -19 -77q0 -61 33 -97.5t88 -36.5h164l10 -10v-162l-10 -10h-164q-123 0 -189.5 69.5t-66.5 153.5q0 119 96 170q-236 8 -373 138.5t-137 363.5zM322 496 q0 -176 99 -266.5t263 -90.5t263.5 90t99.5 267v385q0 172 -100.5 265t-262.5 93t-262 -93t-100 -265v-385z" />
-<glyph unicode="R" horiz-adv-x="1193" d="M190 10v1362l11 10h364q184 0 301 -71q170 -109 170 -336q0 -272 -256 -367q-78 -29 -143 -33l45 -45l240 -288q74 -86 163 -86q4 0 11.5 1t11.5 1l8 -11l-22 -139l-13 -10q-29 -4 -43 -4q-139 0 -272 170l-320 397l-14 8h-70v-559l-10 -10h-151zM362 727h201 q129 0 215 58.5t86 189.5q0 129 -87 189.5t-214 60.5h-201v-498z" />
-<glyph unicode="S" horiz-adv-x="1040" d="M98 113l84 114l19 2q43 -37 127 -63.5t153 -26.5q119 0 194 57.5t75 178.5q0 76 -45.5 130t-114 80.5t-147 61.5t-147.5 71t-114 111.5t-45 180.5q0 178 119 285.5t291 107.5q92 0 177 -22.5t123 -44t52 -36.5l2 -14l-78 -119l-16 -2q-98 74 -252 74q-119 0 -180.5 -61.5 t-61.5 -161.5q0 -84 63.5 -137.5t152.5 -86t179.5 -72.5t154 -126t63.5 -217q0 -111 -40 -192t-108.5 -125t-143.5 -64.5t-159 -20.5q-82 0 -190.5 33t-182.5 90z" />
-<glyph unicode="T" horiz-adv-x="1017" d="M33 1229v143l10 10h961l8 -10l-37 -143l-12 -10h-367v-1209l-10 -10h-152l-10 10v1209h-381z" />
-<glyph unicode="U" horiz-adv-x="1423" d="M176 477v885l10 12l152 21l10 -9v-890q0 -176 100.5 -266.5t262.5 -90.5q168 0 265 90t97 267v866l10 12l152 21l10 -9v-909q0 -244 -141 -373t-393 -129q-250 0 -392.5 129t-142.5 373z" />
-<glyph unicode="V" horiz-adv-x="1216" d="M27 1360l10 12l162 23l12 -9l356 -1085l39 -135l37 135l352 1057l11 12l178 25l12 -9l-494 -1390l-14 -10l-178 28l-12 13z" />
-<glyph unicode="W" horiz-adv-x="1781" d="M29 1360l10 12l162 23l12 -9l317 -1021l41 -152l31 152l213 759v238l10 12l152 21l10 -9v-286l201 -735l31 -152l36 152l293 993l11 12l180 25l12 -9l-461 -1390l-14 -10l-148 28l-12 13l-192 692l-29 137l-29 -137l-204 -723l-15 -10l-151 28l-13 13z" />
-<glyph unicode="X" horiz-adv-x="1177" d="M55 10l426 697l-387 653l10 12l156 23l12 -6l283 -500l35 -70l33 70l264 469l12 12l186 25l13 -9l-400 -679l422 -697l-6 -10h-184l-12 10l-295 516l-33 70l-35 -70l-293 -516l-12 -10h-187z" />
-<glyph unicode="Y" horiz-adv-x="1052" d="M25 1358l10 14l172 23l12 -9l275 -544l32 -80l35 80l260 516l10 12l187 25l12 -9l-418 -780v-596l-10 -10h-151l-11 10v596z" />
-<glyph unicode="Z" horiz-adv-x="1077" d="M92 111l660 1108h-627l-8 10l20 143l13 10h813l10 -10v-100l-658 -1108h643l11 -10v-144l-11 -10h-833l-12 10z" />
-<glyph unicode="[" horiz-adv-x="630" d="M188 -231v1603l11 10h352l8 -10l-39 -119l-12 -10h-162v-1345h162l12 -11l39 -118l-8 -11h-352z" />
-<glyph unicode="\" horiz-adv-x="700" d="M72 1364l10 12l125 19l10 -9l412 -1529l-6 -11h-138l-12 13z" />
-<glyph unicode="]" horiz-adv-x="630" d="M72 -231l39 118l12 11h162v1345h-162l-12 10l-39 119l8 10h352l10 -10v-1603l-10 -11h-352z" />
-<glyph unicode="^" horiz-adv-x="1030" d="M4 553l408 807l14 10l168 25l10 -9l422 -833l-6 -10h-154l-10 10l-342 682l-340 -682l-10 -10h-154z" />
-<glyph unicode="_" horiz-adv-x="1138" d="M72 -10l10 10h975l10 -10v-129l-10 -11h-975l-10 11v129z" />
-<glyph unicode="`" d="M289 1427l10 9h221l15 -9l122 -208l-2 -13l-102 -41h-12z" />
-<glyph unicode="a" horiz-adv-x="970" d="M82 276q0 143 98 224q96 78 320 78h71q57 0 91 20v96q0 195 -211 195q-127 0 -203 -62l-17 2l-69 103l4 16q113 88 287 88q170 0 271 -74.5t101 -236.5v-524l52 -181l-11 -12l-125 -18l-12 8l-59 147q-2 -6 -7.5 -18t-26 -41t-48 -51.5t-79.5 -41t-116 -18.5 q-127 0 -219 72.5t-92 228.5zM254 274q0 -68 45 -109.5t121 -41.5q102 0 242 59v346q-31 -102 -181 -102h-49q-70 0 -124 -34t-54 -118z" />
-<glyph unicode="b" horiz-adv-x="1032" d="M156 23v1433l10 12l143 21l10 -8v-514l-10 -90q72 160 285 159q141 0 228 -93t87 -265v-348q0 -168 -104.5 -261.5t-267.5 -93.5q-55 0 -116 14.5t-93 26.5l-31 15l-131 -19zM319 160q98 -37 201 -37q104 0 164.5 62.5t60.5 179.5v284q0 125 -61 182.5t-160 57.5 q-35 0 -205 -47v-682z" />
-<glyph unicode="c" horiz-adv-x="966" d="M121 330v350q0 160 106.5 258t292.5 98q119 0 213 -53t135 -156l-6 -12l-123 -43l-14 4q-59 113 -215 113q-104 0 -164.5 -62.5t-60.5 -179.5v-282q0 -117 60.5 -179.5t164.5 -62.5q166 0 225 108l15 5l122 -43l7 -13q-39 -98 -133.5 -151.5t-225.5 -53.5 q-186 0 -292.5 97.5t-106.5 257.5z" />
-<glyph unicode="d" horiz-adv-x="1038" d="M123 336v346q0 168 103.5 261t269.5 93q127 0 225 -69l-8 90v399l10 12l143 21l11 -8v-1280l51 -181l-10 -12l-125 -18l-13 8l-59 147q-23 -70 -91.5 -120t-193.5 -50q-141 0 -227 94.5t-86 266.5zM287 371q0 -127 60.5 -187.5t156.5 -60.5q25 0 77 14.5t91 28.5l41 14 v492q0 217 -211 217q-96 0 -155.5 -62.5t-59.5 -177.5v-278z" />
-<glyph unicode="e" horiz-adv-x="976" d="M121 330v344q0 170 106.5 266t282.5 96q182 0 270 -90t88 -213q0 -147 -93 -224t-245 -77q-90 0 -153.5 28.5t-78.5 48t-24 38.5l11 -76v-106q0 -117 61.5 -179.5t167.5 -62.5q160 0 223 108l15 5l122 -43l7 -13q-37 -98 -132.5 -151.5t-226.5 -53.5q-190 0 -295.5 90.5 t-105.5 264.5zM285 614q88 -37 198 -36q213 0 213 163q0 59 -48 103.5t-144 44.5q-106 0 -162.5 -60.5t-56.5 -177.5v-37z" />
-<glyph unicode="f" horiz-adv-x="663" d="M63 874v127l11 11h133v215q0 160 109.5 248t261.5 88q111 0 200 -47l2 -15l-78 -112l-14 -5q-49 23 -110 23q-88 0 -147.5 -44t-59.5 -128v-223h321l10 -11l-38 -127l-15 -10h-278v-1108l-41 -207l-13 -14l-100 59l-10 19v1251h-133z" />
-<glyph unicode="g" horiz-adv-x="995" d="M80 -276l4 14l123 55l14 -4l6 -12q4 -8 24.5 -27.5t49.5 -35t83 -28t122 -12.5q106 0 165.5 42t59.5 104q0 47 -37 82t-100 35h-127q-121 0 -189.5 56t-68.5 132q0 113 92 170q-8 2 -23.5 8t-53.5 31.5t-66.5 61.5t-52 103.5t-23.5 149.5q0 178 102.5 275.5t282.5 97.5 h203l225 47l12 -8l21 -113l-8 -14l-140 -39q49 -29 75 -98.5t26 -151.5q0 -172 -105.5 -275.5t-288.5 -103.5l-131 10q-12 -31 -12 -61q0 -61 33 -96t90 -35h127q145 0 223 -75t78 -195q0 -137 -113.5 -212t-271.5 -75q-334 0 -430 197zM244 649q0 -238 233 -237 q242 0 242 237q0 240 -242 240q-109 0 -171 -61.5t-62 -178.5z" />
-<glyph unicode="h" horiz-adv-x="1069" d="M156 10v1446l10 12l143 21l10 -8v-514l-10 -90q8 20 24.5 41.5t50.5 51t91 48t129 18.5q141 0 228.5 -92t87.5 -262v-672l-11 -10h-143l-10 10v639q0 125 -61.5 182.5t-159.5 57.5q-45 0 -216 -47v-832l-10 -10h-143z" />
-<glyph unicode="i" horiz-adv-x="473" d="M141 1255v170l11 11h170l10 -11v-170l-10 -10h-170zM154 10v979l10 12l143 21l10 -8v-1004l-10 -10h-143z" />
-<glyph unicode="j" horiz-adv-x="473" d="M-256 -381l66 119l10 2q63 -66 157 -66q68 0 122.5 61.5t54.5 184.5v1069l10 12l143 21l10 -8v-1106q0 -178 -89 -279.5t-242 -101.5q-129 0 -238 80zM141 1255v170l11 11h170l10 -11v-170l-10 -10h-170z" />
-<glyph unicode="k" horiz-adv-x="972" d="M156 10v1446l10 12l143 21l10 -8v-838h17l293 350l14 8l215 21l10 -10l-329 -361l-47 -41l43 -49l213 -323q68 -98 149 -99q18 0 29 2l10 -10l-23 -131l-10 -10q-12 -2 -35 -2q-72 0 -132 34.5t-82.5 62.5t-53.5 75l-264 411h-17v-561l-8 -10h-147z" />
-<glyph unicode="l" horiz-adv-x="505" d="M152 225v1231l10 12l143 21l10 -8v-1245q0 -53 29 -73t64 -20h8l8 -10l-23 -129l-10 -10h-16q-31 0 -60.5 7t-70.5 27.5t-66.5 70.5t-25.5 126z" />
-<glyph unicode="m" horiz-adv-x="1617" d="M111 991l10 13l125 18l12 -8l57 -144q6 16 19.5 38t44.5 53.5t89 53t134 21.5q182 0 254 -151q16 31 43 59.5t96.5 60t159.5 31.5q139 0 226 -92t87 -262v-672l-10 -10h-145l-8 10v639q0 123 -60.5 180.5t-157.5 57.5q-66 0 -213 -45q23 -76 23 -144v-688l-10 -10h-144 l-10 10v639q0 240 -198 240q-31 0 -209 -47v-832l-11 -10h-143l-10 10v789z" />
-<glyph unicode="n" horiz-adv-x="1075" d="M111 991l10 13l125 18l12 -8l57 -144q6 16 19.5 38t44.5 53.5t89 53t134 21.5q141 0 233.5 -93t92.5 -261v-672l-10 -10h-144l-10 10v639q0 123 -65.5 181.5t-163.5 58.5q-31 0 -209 -47v-832l-11 -10h-143l-10 10v789z" />
-<glyph unicode="o" d="M121 330v352q0 168 109.5 261t283.5 93t283.5 -93t109.5 -261v-352q0 -168 -109.5 -261.5t-283.5 -93.5t-283.5 93.5t-109.5 261.5zM285 365q0 -119 59 -180.5t170 -61.5q109 0 169 62.5t60 179.5v284q0 117 -60 178.5t-169 61.5q-111 0 -170 -61.5t-59 -178.5v-284z" />
-<glyph unicode="p" horiz-adv-x="1040" d="M111 991l10 13l125 18l12 -8l57 -144q6 16 19.5 38t44.5 53.5t89 53t134 21.5q141 0 228.5 -92t87.5 -262v-352q0 -168 -104.5 -261.5t-270.5 -93.5q-131 0 -226 72l9 -94v-383l-11 -12l-143 -21l-10 8v1254zM326 340q0 -217 211 -217q96 0 156.5 63.5t60.5 178.5v284 q0 123 -61.5 181.5t-157.5 58.5q-31 0 -209 -47v-502z" />
-<glyph unicode="q" horiz-adv-x="1034" d="M123 334v348q0 168 104.5 261t268.5 93q53 0 112.5 -16t91.5 -33l31 -14l135 37l11 -11v-1429l-11 -12l-143 -21l-10 8v500l10 90q-72 -160 -285 -160q-141 0 -228 93.5t-87 265.5zM287 362q0 -125 61.5 -182t159.5 -57q35 0 205 47v502q0 217 -211 217 q-98 0 -156.5 -63.5t-58.5 -178.5v-285z" />
-<glyph unicode="r" horiz-adv-x="632" d="M111 991l10 13l125 18l12 -8l57 -144q6 16 19.5 38t43.5 53.5t87 53t131 21.5l10 -12l-31 -172l-14 -10q-37 18 -106 18q-66 0 -129 -18v-832l-11 -10h-143l-10 10v789z" />
-<glyph unicode="s" horiz-adv-x="866" d="M96 82l78 108l16 3q31 -27 97.5 -48.5t115.5 -21.5q205 0 205 160q0 57 -52 92t-126 56.5t-148.5 50t-127 92t-52.5 161.5q0 147 108.5 224t260.5 77q150 0 264 -80l4 -14l-80 -108h-14q-82 55 -170 55q-92 0 -148.5 -41t-56.5 -113q0 -61 52.5 -98t126 -57.5t148.5 -46 t127 -88t52 -162.5q0 -307 -366 -308q-188 0 -312 95z" />
-<glyph unicode="t" horiz-adv-x="776" d="M61 874v127l11 11h118l19 207l10 12l117 16l10 -8v-227h340l10 -11l-39 -127l-14 -10h-297v-493q0 -106 49 -175t131 -69q78 0 152 63l14 -2l64 -116l-4 -15q-117 -82 -240 -82q-145 0 -237.5 99.5t-92.5 283.5v506h-110z" />
-<glyph unicode="u" horiz-adv-x="1060" d="M145 336v653l11 12l143 21l10 -8v-643q0 -127 60.5 -187.5t156.5 -60.5q25 0 77 14.5t93 28.5l39 14v809l10 12l144 21l10 -8v-813l51 -181l-10 -12l-125 -18l-12 8l-60 147q-23 -70 -91 -120t-193 -50q-141 0 -227.5 94.5t-86.5 266.5z" />
-<glyph unicode="v" horiz-adv-x="946" d="M29 989l10 12l158 21l10 -8l242 -735l28 -109l29 109l233 712l13 10l163 21l7 -10l-375 -1018l-15 -8l-124 28l-15 13z" />
-<glyph unicode="w" horiz-adv-x="1495" d="M29 989l10 12l154 21l10 -8l248 -735l28 -109l29 109l166 499v211l10 12l141 21l11 -8v-262l153 -473l29 -109l29 109l237 712l12 10l166 21l6 -10l-372 -1014l-15 -12l-139 28l-12 13l-158 479l-24 100l-27 -100l-166 -508l-14 -12l-138 26l-12 13z" />
-<glyph unicode="x" horiz-adv-x="997" d="M55 10l346 502l-329 477l10 12l149 21l15 -8l219 -340l31 -56l28 56l205 317l16 10l173 21l12 -8l-338 -494l352 -510l-8 -10h-168l-16 10l-228 350l-28 52l-27 -52l-225 -350l-17 -10h-164z" />
-<glyph unicode="y" horiz-adv-x="952" d="M-68 -377l62 111l14 4q66 -63 160 -64q123 0 190 187l64 172l-23 8l-16 14l-352 934l10 12l160 21l10 -8l240 -738l30 -108l25 90l233 733l13 10l163 21l7 -10l-428 -1219q-92 -266 -322 -266q-127 0 -235 80z" />
-<glyph unicode="z" horiz-adv-x="882" d="M84 102l494 762h-469l-11 10l23 127l14 11h641l10 -11v-96l-499 -758h487l10 -10v-127l-10 -10h-655l-15 10z" />
-<glyph unicode="{" horiz-adv-x="786" d="M78 573l37 123l14 11q86 23 116.5 73.5t30.5 137.5v137q0 154 102.5 245t280.5 91h48l8 -11l-37 -118l-12 -11q-109 0 -172.5 -58t-63.5 -175v-96q0 -104 -45 -182t-131 -113q176 -78 176 -277v-217q0 -119 63.5 -178t172.5 -59l12 -11l37 -118l-8 -11h-48 q-178 0 -280.5 93.5t-102.5 246.5v246q0 94 -40.5 150.5t-149.5 70.5z" />
-<glyph unicode="|" horiz-adv-x="524" d="M178 -440v1894l10 12l144 21l10 -8v-1919l-10 -11h-144z" />
-<glyph unicode="}" horiz-adv-x="784" d="M72 -233l37 118l12 11q109 0 172 59t63 178v217q0 199 176 277q-86 35 -131 112.5t-45 182.5v96q0 117 -63.5 175t-171.5 58l-12 11l-37 118l8 11h47q178 0 280.5 -91.5t102.5 -244.5v-137q0 -104 38 -149.5t148 -72.5l9 -14l-37 -117l-15 -10q-143 -41 -143 -213v-246 q0 -154 -102.5 -247t-280.5 -93h-47z" />
-<glyph unicode="~" horiz-adv-x="1204" d="M125 553q0 168 79 252t202 84q72 0 133 -31t95 -68.5t78 -68.5t87 -31q137 0 137 180l10 11h137l11 -11q0 -168 -79 -251.5t-202 -83.5q-72 0 -133.5 30.5t-95 68.5t-77.5 68.5t-87 30.5q-137 0 -137 -180l-11 -10h-137z" />
-<glyph unicode="&#xa1;" horiz-adv-x="522" d="M158 -465l39 1086l10 10h108l11 -10l43 -1057l-11 -13l-188 -24zM160 815v186l10 11h182l10 -11v-186l-10 -10h-182z" />
-<glyph unicode="&#xa2;" horiz-adv-x="1064" d="M115 557v64q0 170 106.5 270t267.5 121v155l11 13l98 14l10 -8v-172q254 -23 350 -201l-6 -12l-125 -51l-14 4q-59 92 -205 110v-555q145 18 205 113l14 4l123 -51l6 -13q-96 -182 -348 -200v-152l-10 -10h-98l-11 10v154q-162 18 -268 120.5t-106 272.5zM279 561 q0 -96 58 -162.5t152 -85.5v547q-94 -18 -152 -83.5t-58 -160.5v-55z" />
-<glyph unicode="&#xa3;" horiz-adv-x="1193" d="M113 98l6 13q12 0 32.5 2t56.5 24.5t42 63.5l47 348h-170l-10 10v127l10 10h184l21 162q20 158 116.5 249t239.5 91q164 -2 262 -74l2 -14l-45 -113l-14 -4q-86 57 -207 58q-72 0 -124 -55.5t-68 -174.5l-17 -125h332l8 -10l-37 -127l-12 -10h-307l-39 -305l-25 -103h49 q70 0 179.5 -42t162.5 -42q68 0 114 43t46 133q0 25 -5 51.5t-9 39.5l-6 14l8 12l123 25l14 -6q27 -84 27 -142q0 -156 -83 -236.5t-210 -80.5q-66 0 -190.5 45t-188.5 45q-41 0 -103.5 -8t-105.5 -17l-43 -10l-12 6z" />
-<glyph unicode="&#xa5;" horiz-adv-x="1138" d="M121 1157l10 14l168 23l12 -8l221 -443l33 -79l35 79l209 414l10 12l182 25l13 -8l-215 -398h213l8 -10l-35 -123l-12 -10h-252l-74 -137v-59h320l8 -11l-35 -123l-12 -10h-281v-295l-10 -10h-143l-11 10v295h-319l-10 10v123l10 11h319v59l-77 137h-242l-10 10v123 l10 10h162z" />
-<glyph unicode="&#xa6;" horiz-adv-x="561" d="M199 330l10 10h143l10 -10v-770l-10 -11h-143l-10 11v770zM199 707v747l8 12l143 23l12 -8v-774l-10 -11h-143z" />
-<glyph unicode="&#xa7;" horiz-adv-x="868" d="M72 -305l96 96l14 -4q80 -88 209 -88q74 0 127 42t53 118q0 16 -4 41l-161 1167l8 20l90 70l12 -12l66 -201l137 -983q8 -57 8 -90q0 -150 -87 -237t-249 -87q-193 0 -319 134v14zM141 1079q0 150 87 237t249 87q193 0 320 -133v-15l-97 -96l-14 4q-80 88 -209 88 q-74 0 -127 -42t-53 -117q0 -16 4 -41l162 -1168l-8 -20l-90 -70l-13 12l-65 201l-137 983q-9 57 -9 90z" />
-<glyph unicode="&#xa8;" d="M289 1260v159l10 11h150l10 -11v-159l-10 -11h-150zM569 1260v159l11 11h149l10 -11v-159l-10 -11h-149z" />
-<glyph unicode="&#xa9;" horiz-adv-x="1613" d="M125 565v244q0 195 103.5 334t255 201.5t323.5 62.5q176 0 326.5 -62.5t253 -201.5t102.5 -334v-244q0 -147 -58.5 -265t-156.5 -189.5t-218 -108.5t-249 -37q-172 0 -323.5 62.5t-255 202.5t-103.5 335zM258 606q0 -172 78 -290.5t198.5 -170t272.5 -51.5 q240 0 394.5 128t154.5 384v160q0 256 -154.5 384t-394.5 128q-238 0 -393.5 -128t-155.5 -384v-160zM487 565v236q0 150 86 230.5t238 80.5q109 0 189.5 -50t111.5 -136l-6 -13l-105 -41l-14 5q-70 100 -176 100q-82 0 -133 -48t-51 -136v-220q0 -88 51 -135t133 -47 q137 0 188 111l15 4l102 -37l6 -12q-61 -201 -311 -201q-154 0 -239 79.5t-85 229.5z" />
-<glyph unicode="&#xaa;" horiz-adv-x="690" d="M96 934q0 94 50.5 141t138.5 47h108l35 8v52q0 94 -109 94q-66 0 -122 -39l-17 2l-51 78l4 16q84 63 186 64q106 0 171 -49.5t65 -149.5v-301l25 -121l-11 -12l-92 -12l-12 8l-27 86q-2 -4 -4 -10.5t-14 -23.5t-27.5 -30.5t-44.5 -23.5t-63 -10q-78 0 -133.5 50 t-55.5 136zM223 934q0 -33 22.5 -53.5t57.5 -20.5q20 0 51 6t52 15l22 6v182q-33 -57 -96 -57h-45q-31 0 -47.5 -22.5t-16.5 -55.5z" />
-<glyph unicode="&#xab;" horiz-adv-x="1024" d="M90 500v14l258 389l19 12h153l12 -14l-266 -393l266 -393l-12 -15h-153l-19 13zM477 500v14l258 389l19 12h153l13 -14l-267 -393l267 -393l-13 -15h-153l-19 13z" />
-<glyph unicode="&#xac;" horiz-adv-x="1071" d="M72 492v61l6 14l815 465l12 -4l66 -115l-4 -14l-29 -27l-133 -350l133 -350l29 -27l4 -14l-66 -115l-12 -4l-815 465z" />
-<glyph unicode="&#xad;" horiz-adv-x="870" d="M170 459v143l10 10h527l8 -10l-37 -143l-12 -10h-486z" />
-<glyph unicode="&#xae;" horiz-adv-x="966" d="M98 934v133q0 160 116 248t269 88q156 0 270.5 -88t114.5 -248v-133q0 -162 -114.5 -250t-270.5 -88q-154 0 -269.5 88t-115.5 250zM193 956q0 -137 82.5 -206.5t207.5 -69.5q127 0 209 69.5t82 206.5v86q0 139 -82 208t-209 69q-125 0 -207.5 -68.5t-82.5 -208.5v-86z M342 772v453l10 10h127q172 0 172 -145q0 -51 -31.5 -86t-78.5 -46l69 -92q14 -16 45 -16h7l10 -10l-10 -68l-11 -10h-24q-59 0 -97 59l-86 131h-4v-180l-10 -10h-78zM440 1028h39q31 0 52.5 15.5t21.5 46.5q0 57 -74 57h-39v-119z" />
-<glyph unicode="&#xaf;" horiz-adv-x="1030" d="M285 1255v119l10 10h459l8 -10l-25 -119l-12 -10h-430z" />
-<glyph unicode="&#xb0;" horiz-adv-x="724" d="M90 1118v51q0 111 80 172.5t192.5 61.5t192.5 -61.5t80 -172.5v-51q0 -113 -81 -174t-191.5 -61t-191.5 61t-81 174zM221 1143q0 -135 141.5 -135t141.5 135t-141.5 135t-141.5 -135z" />
-<glyph unicode="&#xb1;" horiz-adv-x="1126" d="M193 -55l10 10h733l8 -10l-37 -142l-12 -10h-692l-10 10v142zM193 465v129l10 10h264v293l10 12l144 21l10 -8v-318h297l8 -10l-33 -129l-12 -10h-260v-330l-10 -10h-144l-10 10v330h-264z" />
-<glyph unicode="&#xb2;" horiz-adv-x="747" d="M98 1427v11l12 16q7 10 31.5 38t52 48.5t72.5 36.5t94 16q104 0 181 -66.5t77 -180.5q0 -74 -50 -153t-110 -133l-118 -108q-57 -53 -68 -78h367l8 -10l-29 -106l-12 -10h-479l-12 10l-15 63q2 55 61.5 125t130 128.5t128 132t57.5 132.5q0 51 -33.5 89t-87.5 38 q-88 0 -159 -102h-11z" />
-<glyph unicode="&#xb3;" horiz-adv-x="739" d="M78 897l2 12l92 70h16q6 -12 19.5 -30.5t57.5 -50.5t93 -32q59 0 103.5 33t44.5 88v21q0 55 -47 85.5t-133 30.5h-76l-8 11l37 104l12 10h35q162 0 161 109q0 57 -37.5 84.5t-99.5 27.5q-31 0 -59.5 -12t-44 -25.5t-32.5 -32t-21 -20.5l-17 -2l-88 60v14q4 6 11 15.5 t32 35t52.5 45t72.5 34.5t94 15q121 0 196 -63.5t75 -173.5q0 -119 -97 -170q115 -45 115 -166v-47q0 -111 -82 -174.5t-199 -63.5q-168 0 -266 138z" />
-<glyph unicode="&#xb4;" d="M371 1219l123 208l14 9h221l10 -9l-252 -262h-12l-102 41z" />
-<glyph unicode="&#xb5;" horiz-adv-x="1611" d="M72 492v61l6 14l815 465l12 -4l66 -115l-4 -14l-29 -27l-133 -264h725l10 -10v-152l-10 -10h-725l133 -264l29 -27l4 -14l-66 -115l-12 -4l-815 465z" />
-<glyph unicode="&#x3bc;" horiz-adv-x="1611" d="M72 492v61l6 14l815 465l12 -4l66 -115l-4 -14l-29 -27l-133 -264h725l10 -10v-152l-10 -10h-725l133 -264l29 -27l4 -14l-66 -115l-12 -4l-815 465z" />
-<glyph unicode="&#xb6;" horiz-adv-x="1189" d="M115 733v256q0 199 126 296t312 97h557l8 -10l-20 -137l-13 -10h-374v-1665l-9 -9h-139l-10 9v776q-186 0 -312 98t-126 299zM817 -438v1544l10 10h138l10 -10v-1544l-10 -11h-138z" />
-<glyph unicode="&#xb7;" horiz-adv-x="536" d="M164 442v193l10 10h188l11 -10v-193l-11 -10h-188z" />
-<glyph unicode="&#xb8;" d="M317 -281l27 70l14 6q45 -33 91 -33q139 0 139 138q0 16 -9.5 40.5l-17.5 43.5l-8 16h61q10 -8 26.5 -23.5t43.5 -60.5t27 -86q0 -88 -59.5 -139t-149.5 -51q-117 0 -180 65z" />
-<glyph unicode="&#xb9;" horiz-adv-x="741" d="M106 758v106l11 10h190v582h-139l-12 10l-27 107l8 10h295l10 -10v-699h197l8 -10l-26 -106l-13 -10h-491z" />
-<glyph unicode="&#xba;" horiz-adv-x="708" d="M109 967v209q0 104 68.5 162.5t177 58.5t177 -58.5t68.5 -162.5v-209q0 -104 -68.5 -161.5t-177 -57.5t-177 57.5t-68.5 161.5zM236 989q0 -123 118.5 -123t118.5 123v168q0 119 -118.5 119t-118.5 -119v-168z" />
-<glyph unicode="&#xbb;" horiz-adv-x="1024" d="M104 115l267 393l-267 393l13 14h153l19 -12l258 -389v-14l-258 -387l-19 -13h-153zM492 115l266 393l-266 393l12 14h153l19 -12l258 -389v-14l-258 -387l-19 -13h-153z" />
-<glyph unicode="&#xbc;" horiz-adv-x="1595" d="M88 557v107l10 10h191v581h-139l-13 11l-26 106l8 10h295l10 -10v-698h197l8 -10l-27 -107l-12 -10h-492zM535 10l319 1002l14 8l109 -19l8 -12l-311 -979l-12 -10h-121zM874 301l371 512l15 10l94 19l10 -8v-498h147l9 -10l-29 -105l-10 -10h-117v-195l-10 -12l-115 -16 l-10 8v215h-320l-14 8zM1049 336h182v184l4 78l-45 -72l-109 -153z" />
-<glyph unicode="&#xbd;" horiz-adv-x="1632" d="M88 557v107l10 10h191v581h-139l-13 11l-26 106l8 10h295l10 -10v-698h197l8 -10l-27 -107l-12 -10h-492zM535 10l319 1002l14 8l109 -19l8 -12l-311 -979l-12 -10h-121zM985 680v10l11 17q7 10 32 37.5t52.5 48t72.5 37t94 16.5q104 0 181 -66.5t77 -181.5 q0 -74 -50 -152.5t-110 -133.5l-118 -107q-57 -53 -68 -78h367l8 -10l-29 -107l-12 -10h-479l-13 10l-14 64q2 55 61.5 124.5t130 128t128 132t57.5 133.5q0 51 -34 89t-87 38q-88 0 -160 -103h-10z" />
-<glyph unicode="&#xbe;" horiz-adv-x="1585" d="M80 696l2 13l92 69h16q6 -12 19.5 -30.5t57.5 -50t93 -31.5q59 0 103.5 32.5t44.5 87.5v21q0 55 -47 86t-133 31h-76l-8 10l37 104l12 11h35q162 0 161 108q0 57 -37.5 85t-99.5 28q-31 0 -59.5 -12.5t-44 -25.5t-32.5 -31.5t-21 -20.5l-17 -2l-88 59v14q4 6 11.5 15.5 t32 35t52 45t72.5 35t94 15.5q121 0 196 -63.5t75 -174.5q0 -119 -97 -170q115 -45 115 -166v-47q0 -111 -82 -174t-199 -63q-168 0 -266 137zM528 10l320 1002l14 8l109 -19l8 -12l-311 -979l-13 -10h-120zM864 301l371 512l14 10l94 19l11 -8v-498h147l8 -10l-28 -105 l-11 -10h-116v-195l-11 -12l-114 -16l-10 8v215h-320l-14 8zM1038 336h183v184l4 78l-45 -72l-109 -153z" />
-<glyph unicode="&#xbf;" horiz-adv-x="978" d="M98 94q0 152 96.5 248t249.5 113l7 166l10 10h121l10 -10v-293l-10 -13l-140 -22q-82 -14 -127 -76.5t-45 -157.5v-145q0 -109 60.5 -166t171.5 -57q113 0 177 55t64 168l13 8l141 -31l10 -12q0 -166 -114.5 -259t-290.5 -93t-290 93t-114 259v215zM420 815v186l10 11 h182l11 -11v-186l-11 -10h-182z" />
-<glyph unicode="&#xc0;" horiz-adv-x="1208" d="M25 10l477 1352l12 10l172 23l12 -9l486 -1376l-6 -10h-164l-13 10l-112 330h-572l-110 -330l-10 -10h-166zM358 1763l11 9h221l14 -9l123 -209l-2 -12l-102 -41h-13zM371 496h467l-213 630l-21 88l-20 -88z" />
-<glyph unicode="&#xc1;" horiz-adv-x="1208" d="M25 10l477 1352l12 10l172 23l12 -9l486 -1376l-6 -10h-164l-13 10l-112 330h-572l-110 -330l-10 -10h-166zM371 496h467l-213 630l-21 88l-20 -88zM479 1554l123 209l14 9h222l10 -9l-252 -262h-12l-103 41z" />
-<glyph unicode="&#xc2;" horiz-adv-x="1208" d="M25 10l477 1352l12 10l172 23l12 -9l486 -1376l-6 -10h-164l-13 10l-112 330h-572l-110 -330l-10 -10h-166zM334 1552l188 209l19 11h123l18 -11l188 -209l-4 -14l-112 -37h-15l-137 160l-137 -160h-14l-113 37zM371 496h467l-213 630l-21 88l-20 -88z" />
-<glyph unicode="&#xc3;" horiz-adv-x="1208" d="M25 10l477 1352l12 10l172 23l12 -9l486 -1376l-6 -10h-164l-13 10l-112 330h-572l-110 -330l-10 -10h-166zM313 1604v14q43 72 86 103.5t109 31.5q61 0 116.5 -47t84.5 -47q31 0 98 67l14 5l74 -56v-14q-76 -135 -199 -135q-57 0 -114.5 46t-83.5 46q-37 0 -97 -66 l-14 -4zM371 496h467l-213 630l-21 88l-20 -88z" />
-<glyph unicode="&#xc4;" horiz-adv-x="1208" d="M25 10l477 1352l12 10l172 23l12 -9l486 -1376l-6 -10h-164l-13 10l-112 330h-572l-110 -330l-10 -10h-166zM371 496h467l-213 630l-21 88l-20 -88zM379 1595v160l10 10h150l10 -10v-160l-10 -10h-150zM659 1595v160l11 10h149l10 -10v-160l-10 -10h-149z" />
-<glyph unicode="&#xc5;" horiz-adv-x="1208" d="M25 10l477 1352l12 10l172 23l12 -9l486 -1376l-6 -10h-164l-13 10l-112 330h-572l-110 -330l-10 -10h-166zM371 496h467l-213 630l-21 88l-20 -88zM430 1636v27q0 63 49 98t117 35t117 -35t49 -98v-27q0 -63 -49 -99t-117 -36t-117 36t-49 99zM520 1648.5 q0 -67.5 76 -67.5t76 67.5t-76 67.5t-76 -67.5z" />
-<glyph unicode="&#xc6;" horiz-adv-x="1568" d="M18 10l529 1362l12 10h827l11 -10v-143l-11 -10h-569l84 -410h477l11 -10l-29 -144l-12 -10h-412l98 -481h420l8 -10l-20 -144l-12 -10h-527l-12 10l-68 326h-493l-119 -326l-10 -10h-176zM391 500h400l-127 626l-17 93l-24 -93z" />
-<glyph unicode="&#xc7;" horiz-adv-x="1284" d="M145 477v418q0 244 145.5 376t391.5 132q170 0 297 -74t182 -209l-6 -12l-137 -57l-14 4q-41 86 -127 135t-195 49q-162 0 -261 -93t-99 -265v-385q0 -176 98 -266.5t262 -90.5q258 0 346 191l14 4l134 -51l6 -13q-94 -270 -447 -293q72 -72 72 -147q0 -88 -59.5 -139 t-149.5 -51q-117 0 -180 65l-4 14l26 70l15 6q45 -33 90 -33q139 0 139 138q0 27 -22 75q-240 6 -378.5 135t-138.5 367z" />
-<glyph unicode="&#xc8;" horiz-adv-x="1050" d="M190 10v1362l11 10h710l11 -10v-143l-11 -10h-549v-410h478l8 -10l-37 -144l-12 -10h-437v-481h551l9 -10l-21 -144l-12 -10h-688zM330 1763l10 9h221l14 -9l123 -209l-2 -12l-102 -41h-12z" />
-<glyph unicode="&#xc9;" horiz-adv-x="1050" d="M190 10v1362l11 10h710l11 -10v-143l-11 -10h-549v-410h478l8 -10l-37 -144l-12 -10h-437v-481h551l9 -10l-21 -144l-12 -10h-688zM457 1554l123 209l14 9h221l10 -9l-252 -262h-12l-102 41z" />
-<glyph unicode="&#xca;" horiz-adv-x="1050" d="M190 10v1362l11 10h710l11 -10v-143l-11 -10h-549v-410h478l8 -10l-37 -144l-12 -10h-437v-481h551l9 -10l-21 -144l-12 -10h-688zM303 1552l189 209l18 11h123l18 -11l189 -209l-4 -14l-113 -37h-14l-138 160l-137 -160h-14l-113 37z" />
-<glyph unicode="&#xcb;" horiz-adv-x="1050" d="M190 10v1362l11 10h710l11 -10v-143l-11 -10h-549v-410h478l8 -10l-37 -144l-12 -10h-437v-481h551l9 -10l-21 -144l-12 -10h-688zM348 1595v160l10 10h150l10 -10v-160l-10 -10h-150zM629 1595v160l10 10h149l11 -10v-160l-11 -10h-149z" />
-<glyph unicode="&#xcc;" horiz-adv-x="555" d="M31 1763l10 9h221l14 -9l123 -209l-2 -12l-102 -41h-12zM190 10v1352l11 12l151 21l10 -9v-1376l-10 -10h-151z" />
-<glyph unicode="&#xcd;" horiz-adv-x="555" d="M158 1554l123 209l14 9h221l10 -9l-252 -262h-12l-102 41zM190 10v1352l11 12l151 21l10 -9v-1376l-10 -10h-151z" />
-<glyph unicode="&#xce;" horiz-adv-x="555" d="M8 1552l189 209l18 11h123l18 -11l189 -209l-4 -14l-113 -37h-14l-138 160l-137 -160h-14l-113 37zM190 10v1352l11 12l151 21l10 -9v-1376l-10 -10h-151z" />
-<glyph unicode="&#xcf;" horiz-adv-x="555" d="M49 1595v160l10 10h150l10 -10v-160l-10 -10h-150zM190 10v1352l11 12l151 21l10 -9v-1376l-10 -10h-151zM330 1595v160l10 10h149l11 -10v-160l-11 -10h-149z" />
-<glyph unicode="&#xd0;" horiz-adv-x="1372" d="M115 616v144l10 10h94v602l10 10h453q250 0 397.5 -131t147.5 -370v-383q0 -242 -146.5 -370t-398.5 -128h-453l-10 10v596h-94zM391 164h291q166 0 267.5 88t101.5 264v346q0 174 -102.5 265.5t-266.5 91.5h-291v-449h260l8 -10l-36 -144l-13 -10h-219v-442z" />
-<glyph unicode="&#xd1;" horiz-adv-x="1447" d="M190 10v1352l11 12l151 21l15 -9l663 -999l53 -98v1073l11 12l151 21l10 -9v-1376l-10 -10h-145l-17 10l-667 1008l-54 98v-1106l-10 -10h-151zM449 1604v14q43 72 86 103.5t108 31.5q61 0 116.5 -47t84.5 -47q31 0 98 67l14 5l74 -56v-14q-76 -135 -199 -135 q-57 0 -114.5 46t-83.5 46q-37 0 -96 -66l-15 -4z" />
-<glyph unicode="&#xd2;" horiz-adv-x="1368" d="M145 477v418q0 244 146.5 376t392.5 132t392.5 -132t146.5 -376v-418q0 -242 -145.5 -372t-393.5 -130t-393.5 130t-145.5 372zM322 496q0 -176 99 -266.5t263 -90.5t263.5 90t99.5 267v385q0 172 -100.5 265t-262.5 93t-262 -93t-100 -265v-385zM434 1763l10 9h222 l14 -9l123 -209l-2 -12l-103 -41h-12z" />
-<glyph unicode="&#xd3;" horiz-adv-x="1368" d="M145 477v418q0 244 146.5 376t392.5 132t392.5 -132t146.5 -376v-418q0 -242 -145.5 -372t-393.5 -130t-393.5 130t-145.5 372zM322 496q0 -176 99 -266.5t263 -90.5t263.5 90t99.5 267v385q0 172 -100.5 265t-262.5 93t-262 -93t-100 -265v-385zM571 1554l123 209l15 9 h221l10 -9l-252 -262h-12l-103 41z" />
-<glyph unicode="&#xd4;" horiz-adv-x="1368" d="M145 477v418q0 244 146.5 376t392.5 132t392.5 -132t146.5 -376v-418q0 -242 -145.5 -372t-393.5 -130t-393.5 130t-145.5 372zM322 496q0 -176 99 -266.5t263 -90.5t263.5 90t99.5 267v385q0 172 -100.5 265t-262.5 93t-262 -93t-100 -265v-385zM418 1552l188 209l19 11 h123l18 -11l188 -209l-4 -14l-112 -37h-15l-137 160l-137 -160h-14l-113 37z" />
-<glyph unicode="&#xd5;" horiz-adv-x="1368" d="M145 477v418q0 244 146.5 376t392.5 132t392.5 -132t146.5 -376v-418q0 -242 -145.5 -372t-393.5 -130t-393.5 130t-145.5 372zM322 496q0 -176 99 -266.5t263 -90.5t263.5 90t99.5 267v385q0 172 -100.5 265t-262.5 93t-262 -93t-100 -265v-385zM397 1604v14 q43 72 86 103.5t109 31.5q61 0 116.5 -47t84.5 -47q31 0 98 67l14 5l74 -56v-14q-78 -135 -199 -135q-59 0 -114.5 46t-83.5 46q-37 0 -97 -66l-14 -4z" />
-<glyph unicode="&#xd6;" horiz-adv-x="1368" d="M145 477v418q0 244 146.5 376t392.5 132t392.5 -132t146.5 -376v-418q0 -242 -145.5 -372t-393.5 -130t-393.5 130t-145.5 372zM322 496q0 -176 99 -266.5t263 -90.5t263.5 90t99.5 267v385q0 172 -100.5 265t-262.5 93t-262 -93t-100 -265v-385zM463 1595v160l10 10h150 l10 -10v-160l-10 -10h-150zM743 1595v160l11 10h149l10 -10v-160l-10 -10h-149z" />
-<glyph unicode="&#xd7;" horiz-adv-x="1126" d="M190 799l3 14l116 86l15 -2l249 -250l261 262h14l88 -118l-6 -15l-242 -244l260 -260v-14l-100 -100h-14l-261 258l-264 -264h-14l-100 100v14l264 264z" />
-<glyph unicode="&#xd8;" horiz-adv-x="1368" d="M145 477v418q0 244 146.5 376t392.5 132q184 0 313 -74l54 92l14 4l100 -36l4 -11l-73 -127q127 -137 127 -356v-418q0 -242 -145.5 -372t-393.5 -130q-166 0 -289 60l-65 -113l-13 -4l-92 51l-4 11l72 122q-148 131 -148 375zM322 496q0 -141 65 -230l522 910 q-90 63 -225 63q-162 0 -262 -93t-100 -265v-385zM481 184q84 -45 203 -45q164 0 263.5 90t99.5 267v385q0 115 -50 200z" />
-<glyph unicode="&#xd9;" horiz-adv-x="1423" d="M176 477v885l10 12l152 21l10 -9v-890q0 -176 100.5 -266.5t262.5 -90.5q168 0 265 90t97 267v866l10 12l152 21l10 -9v-909q0 -244 -141 -373t-393 -129q-250 0 -392.5 129t-142.5 373zM467 1763l10 9h221l15 -9l123 -209l-2 -12l-103 -41h-12z" />
-<glyph unicode="&#xda;" horiz-adv-x="1423" d="M176 477v885l10 12l152 21l10 -9v-890q0 -176 100.5 -266.5t262.5 -90.5q168 0 265 90t97 267v866l10 12l152 21l10 -9v-909q0 -244 -141 -373t-393 -129q-250 0 -392.5 129t-142.5 373zM604 1554l123 209l14 9h222l10 -9l-252 -262h-12l-103 41z" />
-<glyph unicode="&#xdb;" horiz-adv-x="1423" d="M176 477v885l10 12l152 21l10 -9v-890q0 -176 100.5 -266.5t262.5 -90.5q168 0 265 90t97 267v866l10 12l152 21l10 -9v-909q0 -244 -141 -373t-393 -129q-250 0 -392.5 129t-142.5 373zM440 1552l189 209l18 11h123l18 -11l189 -209l-4 -14l-113 -37h-14l-137 160 l-138 -160h-14l-113 37z" />
-<glyph unicode="&#xdc;" horiz-adv-x="1423" d="M176 477v885l10 12l152 21l10 -9v-890q0 -176 100.5 -266.5t262.5 -90.5q168 0 265 90t97 267v866l10 12l152 21l10 -9v-909q0 -244 -141 -373t-393 -129q-250 0 -392.5 129t-142.5 373zM485 1595v160l11 10h149l10 -10v-160l-10 -10h-149zM766 1595v160l10 10h150 l10 -10v-160l-10 -10h-150z" />
-<glyph unicode="&#xdd;" horiz-adv-x="1052" d="M25 1358l10 14l172 23l12 -9l275 -544l32 -80l35 80l260 516l10 12l187 25l12 -9l-418 -780v-596l-10 -10h-151l-11 10v596zM401 1554l123 209l15 9h221l10 -9l-252 -262h-12l-103 41z" />
-<glyph unicode="&#xde;" horiz-adv-x="1138" d="M190 10v1352l11 12l151 21l10 -9v-288h199q209 0 324 -68q172 -100 172 -344q0 -193 -117 -318.5t-340 -125.5q-199 0 -248 118l10 -81v-269l-10 -10h-151zM362 430q100 -35 195 -35q145 0 233.5 72t88.5 215q0 258 -318 258h-199v-510z" />
-<glyph unicode="&#xdf;" horiz-adv-x="1224" d="M66 874v127l10 11h123v149q0 160 108.5 244t262 84t262 -84t108.5 -244q0 -76 -36 -139.5t-78 -99t-77.5 -92t-35.5 -121.5q0 -53 46 -84t111.5 -50.5t131 -45t111.5 -87t46 -159.5q0 -307 -366 -308q-186 0 -310 95l-2 12l78 108l16 3q31 -27 97.5 -48.5t115.5 -21.5 q207 0 207 160q0 57 -44 93t-108.5 57.5t-128 47t-107.5 83t-44 145.5q0 80 34 146.5t73 103t72.5 91t33.5 111.5q0 86 -60.5 133t-146.5 47q-88 0 -147.5 -44t-59.5 -128v-1413l-40 -207l-13 -14l-100 59l-10 19v1251h-123z" />
-<glyph unicode="&#xe0;" horiz-adv-x="970" d="M82 276q0 143 98 224q96 78 320 78h71q57 0 91 20v96q0 195 -211 195q-127 0 -203 -62l-17 2l-69 103l4 16q113 88 287 88q170 0 271 -74.5t101 -236.5v-524l52 -181l-11 -12l-125 -18l-12 8l-59 147q-2 -6 -7.5 -18t-26 -41t-48 -51.5t-79.5 -41t-116 -18.5 q-127 0 -219 72.5t-92 228.5zM236 1427l10 9h221l14 -9l123 -208l-2 -13l-102 -41h-13zM254 274q0 -68 45 -109.5t121 -41.5q102 0 242 59v346q-31 -102 -181 -102h-49q-70 0 -124 -34t-54 -118z" />
-<glyph unicode="&#xe1;" horiz-adv-x="970" d="M82 276q0 143 98 224q96 78 320 78h71q57 0 91 20v96q0 195 -211 195q-127 0 -203 -62l-17 2l-69 103l4 16q113 88 287 88q170 0 271 -74.5t101 -236.5v-524l52 -181l-11 -12l-125 -18l-12 8l-59 147q-2 -6 -7.5 -18t-26 -41t-48 -51.5t-79.5 -41t-116 -18.5 q-127 0 -219 72.5t-92 228.5zM254 274q0 -68 45 -109.5t121 -41.5q102 0 242 59v346q-31 -102 -181 -102h-49q-70 0 -124 -34t-54 -118zM373 1219l123 208l14 9h221l10 -9l-252 -262h-12l-102 41z" />
-<glyph unicode="&#xe2;" horiz-adv-x="970" d="M82 276q0 143 98 224q96 78 320 78h71q57 0 91 20v96q0 195 -211 195q-127 0 -203 -62l-17 2l-69 103l4 16q113 88 287 88q170 0 271 -74.5t101 -236.5v-524l52 -181l-11 -12l-125 -18l-12 8l-59 147q-2 -6 -7.5 -18t-26 -41t-48 -51.5t-79.5 -41t-116 -18.5 q-127 0 -219 72.5t-92 228.5zM219 1217l189 208l18 11h123l18 -11l189 -208l-4 -15l-113 -37h-14l-138 160l-137 -160h-14l-113 37zM254 274q0 -68 45 -109.5t121 -41.5q102 0 242 59v346q-31 -102 -181 -102h-49q-70 0 -124 -34t-54 -118z" />
-<glyph unicode="&#xe3;" horiz-adv-x="970" d="M82 276q0 143 98 224q96 78 320 78h71q57 0 91 20v96q0 195 -211 195q-127 0 -203 -62l-17 2l-69 103l4 16q113 88 287 88q170 0 271 -74.5t101 -236.5v-524l52 -181l-11 -12l-125 -18l-12 8l-59 147q-2 -6 -7.5 -18t-26 -41t-48 -51.5t-79.5 -41t-116 -18.5 q-127 0 -219 72.5t-92 228.5zM199 1268v14q43 72 86 103.5t108 31.5q61 0 116.5 -47t84.5 -47q31 0 98 68l15 4l73 -56v-14q-76 -135 -198 -135q-57 0 -114.5 46t-84.5 46q-37 0 -96 -65l-15 -5zM254 274q0 -68 45 -109.5t121 -41.5q102 0 242 59v346q-31 -102 -181 -102 h-49q-70 0 -124 -34t-54 -118z" />
-<glyph unicode="&#xe4;" horiz-adv-x="970" d="M82 276q0 143 98 224q96 78 320 78h71q57 0 91 20v96q0 195 -211 195q-127 0 -203 -62l-17 2l-69 103l4 16q113 88 287 88q170 0 271 -74.5t101 -236.5v-524l52 -181l-11 -12l-125 -18l-12 8l-59 147q-2 -6 -7.5 -18t-26 -41t-48 -51.5t-79.5 -41t-116 -18.5 q-127 0 -219 72.5t-92 228.5zM254 274q0 -68 45 -109.5t121 -41.5q102 0 242 59v346q-31 -102 -181 -102h-49q-70 0 -124 -34t-54 -118zM264 1260v159l10 11h150l10 -11v-159l-10 -11h-150zM545 1260v159l10 11h150l10 -11v-159l-10 -11h-150z" />
-<glyph unicode="&#xe5;" horiz-adv-x="970" d="M82 276q0 143 98 224q96 78 320 78h71q57 0 91 20v96q0 195 -211 195q-127 0 -203 -62l-17 2l-69 103l4 16q113 88 287 88q170 0 271 -74.5t101 -236.5v-524l52 -181l-11 -12l-125 -18l-12 8l-59 147q-2 -6 -7.5 -18t-26 -41t-48 -51.5t-79.5 -41t-116 -18.5 q-127 0 -219 72.5t-92 228.5zM254 274q0 -68 45 -109.5t121 -41.5q102 0 242 59v346q-31 -102 -181 -102h-49q-70 0 -124 -34t-54 -118zM324 1300v27q0 63 49 98t116.5 35t116.5 -34.5t49 -98.5v-27q0 -63 -49 -99t-116.5 -36t-116.5 36t-49 99zM414 1312.5 q0 -67.5 75.5 -67.5t75.5 67.5t-75.5 67.5t-75.5 -67.5z" />
-<glyph unicode="&#xe6;" horiz-adv-x="1513" d="M82 283q0 301 383 301h102q57 0 90 20v90q0 195 -211 195q-127 0 -202 -62l-17 2l-69 103l4 16q113 88 287 88q213 0 303 -127q96 127 288 127q180 0 265.5 -90t85.5 -215q0 -152 -90.5 -229.5t-239.5 -77.5q-201 0 -250 115l10 -76v-98q0 -117 61.5 -179.5t168.5 -62.5 q160 0 223 108l14 5l123 -43l6 -13q-37 -98 -132 -151.5t-226 -53.5q-270 0 -363 172q-10 -20 -27.5 -41.5t-53 -54.5t-95 -54.5t-131.5 -21.5q-131 0 -219 84.5t-88 223.5zM250 283q0 -68 45 -114t121 -46q152 0 258 80q-16 61 -17 127v205q-31 -102 -180 -103h-49 q-70 0 -124 -32.5t-54 -116.5zM821 606q43 -33 215 -33q82 0 136.5 39t54.5 127q0 61 -47 104.5t-146 43.5q-213 0 -213 -236v-45z" />
-<glyph unicode="&#xe7;" horiz-adv-x="966" d="M121 330v350q0 160 106.5 258t292.5 98q119 0 213 -53t135 -156l-6 -12l-123 -43l-14 4q-59 113 -215 113q-104 0 -164.5 -62.5t-60.5 -179.5v-282q0 -117 60.5 -179.5t164.5 -62.5q166 0 225 108l15 5l122 -43l7 -13q-72 -182 -312 -203q72 -72 72 -147 q0 -88 -59.5 -139t-149.5 -51q-117 0 -180 65l-4 14l26 70l15 6q45 -33 90 -33q139 0 139 138q0 27 -22 75q-174 8 -273.5 104.5t-99.5 250.5z" />
-<glyph unicode="&#xe8;" horiz-adv-x="976" d="M121 330v344q0 170 106.5 266t282.5 96q182 0 270 -90t88 -213q0 -147 -93 -224t-245 -77q-90 0 -153.5 28.5t-78.5 48t-24 38.5l11 -76v-106q0 -117 61.5 -179.5t167.5 -62.5q160 0 223 108l15 5l122 -43l7 -13q-37 -98 -132.5 -151.5t-226.5 -53.5q-190 0 -295.5 90.5 t-105.5 264.5zM252 1427l10 9h221l15 -9l123 -208l-3 -13l-102 -41h-12zM285 614q88 -37 198 -36q213 0 213 163q0 59 -48 103.5t-144 44.5q-106 0 -162.5 -60.5t-56.5 -177.5v-37z" />
-<glyph unicode="&#xe9;" horiz-adv-x="976" d="M121 330v344q0 170 106.5 266t282.5 96q182 0 270 -90t88 -213q0 -147 -93 -224t-245 -77q-90 0 -153.5 28.5t-78.5 48t-24 38.5l11 -76v-106q0 -117 61.5 -179.5t167.5 -62.5q160 0 223 108l15 5l122 -43l7 -13q-37 -98 -132.5 -151.5t-226.5 -53.5q-190 0 -295.5 90.5 t-105.5 264.5zM285 614q88 -37 198 -36q213 0 213 163q0 59 -48 103.5t-144 44.5q-106 0 -162.5 -60.5t-56.5 -177.5v-37zM389 1219l123 208l14 9h222l10 -9l-252 -262h-12l-103 41z" />
-<glyph unicode="&#xea;" horiz-adv-x="976" d="M121 330v344q0 170 106.5 266t282.5 96q182 0 270 -90t88 -213q0 -147 -93 -224t-245 -77q-90 0 -153.5 28.5t-78.5 48t-24 38.5l11 -76v-106q0 -117 61.5 -179.5t167.5 -62.5q160 0 223 108l15 5l122 -43l7 -13q-37 -98 -132.5 -151.5t-226.5 -53.5q-190 0 -295.5 90.5 t-105.5 264.5zM236 1217l188 208l18 11h123l19 -11l188 -208l-4 -15l-113 -37h-14l-137 160l-137 -160h-15l-112 37zM285 614q88 -37 198 -36q213 0 213 163q0 59 -48 103.5t-144 44.5q-106 0 -162.5 -60.5t-56.5 -177.5v-37z" />
-<glyph unicode="&#xeb;" horiz-adv-x="976" d="M121 330v344q0 170 106.5 266t282.5 96q182 0 270 -90t88 -213q0 -147 -93 -224t-245 -77q-90 0 -153.5 28.5t-78.5 48t-24 38.5l11 -76v-106q0 -117 61.5 -179.5t167.5 -62.5q160 0 223 108l15 5l122 -43l7 -13q-37 -98 -132.5 -151.5t-226.5 -53.5q-190 0 -295.5 90.5 t-105.5 264.5zM281 1260v159l10 11h149l11 -11v-159l-11 -11h-149zM285 614q88 -37 198 -36q213 0 213 163q0 59 -48 103.5t-144 44.5q-106 0 -162.5 -60.5t-56.5 -177.5v-37zM561 1260v159l10 11h150l10 -11v-159l-10 -11h-150z" />
-<glyph unicode="&#xec;" horiz-adv-x="473" d="M-18 1427l10 9h221l14 -9l123 -208l-2 -13l-102 -41h-13zM154 10v979l10 12l143 21l10 -8v-1004l-10 -10h-143z" />
-<glyph unicode="&#xed;" horiz-adv-x="473" d="M119 1219l123 208l14 9h221l10 -9l-251 -262h-13l-102 41zM154 10v979l10 12l143 21l10 -8v-1004l-10 -10h-143z" />
-<glyph unicode="&#xee;" horiz-adv-x="473" d="M-35 1217l189 208l18 11h123l18 -11l189 -208l-4 -15l-113 -37h-14l-138 160l-137 -160h-14l-113 37zM154 10v979l10 12l143 21l10 -8v-1004l-10 -10h-143z" />
-<glyph unicode="&#xef;" horiz-adv-x="473" d="M10 1260v159l10 11h150l10 -11v-159l-10 -11h-150zM154 10v979l10 12l143 21l10 -8v-1004l-10 -10h-143zM291 1260v159l10 11h150l10 -11v-159l-10 -11h-150z" />
-<glyph unicode="&#xf0;" horiz-adv-x="1024" d="M123 330v291q0 168 103.5 261t269.5 93q127 0 225 -70v56q0 137 -72 237l-221 -113l-12 5l-47 94l2 14l182 92q-63 45 -176 99l-8 14l45 108l16 9q166 -68 268 -154l148 76l12 -2l49 -97l-4 -12l-115 -61q88 -123 89 -269v-671q0 -168 -103.5 -261.5t-277.5 -93.5 q-166 0 -269.5 93.5t-103.5 261.5zM287 365q0 -115 59.5 -178.5t155.5 -63.5t153.5 63.5t57.5 178.5v245q0 217 -211 217q-96 0 -155.5 -62.5t-59.5 -176.5v-223z" />
-<glyph unicode="&#xf1;" horiz-adv-x="1075" d="M111 991l10 13l125 18l12 -8l57 -144q6 16 19.5 38t44.5 53.5t89 53t134 21.5q141 0 233.5 -93t92.5 -261v-672l-10 -10h-144l-10 10v639q0 123 -65.5 181.5t-163.5 58.5q-31 0 -209 -47v-832l-11 -10h-143l-10 10v789zM270 1268v14q43 72 86 103.5t109 31.5 q61 0 116.5 -47t84.5 -47q31 0 98 68l14 4l74 -56v-14q-78 -135 -199 -135q-59 0 -114.5 46t-83.5 46q-37 0 -97 -65l-14 -5z" />
-<glyph unicode="&#xf2;" d="M121 330v352q0 168 109.5 261t283.5 93t283.5 -93t109.5 -261v-352q0 -168 -109.5 -261.5t-283.5 -93.5t-283.5 93.5t-109.5 261.5zM266 1427l10 9h222l14 -9l123 -208l-2 -13l-103 -41h-12zM285 365q0 -119 59 -180.5t170 -61.5q109 0 169 62.5t60 179.5v284 q0 117 -60 178.5t-169 61.5q-111 0 -170 -61.5t-59 -178.5v-284z" />
-<glyph unicode="&#xf3;" d="M121 330v352q0 168 109.5 261t283.5 93t283.5 -93t109.5 -261v-352q0 -168 -109.5 -261.5t-283.5 -93.5t-283.5 93.5t-109.5 261.5zM285 365q0 -119 59 -180.5t170 -61.5q109 0 169 62.5t60 179.5v284q0 117 -60 178.5t-169 61.5q-111 0 -170 -61.5t-59 -178.5v-284z M403 1219l123 208l15 9h221l10 -9l-252 -262h-12l-102 41z" />
-<glyph unicode="&#xf4;" d="M121 330v352q0 168 109.5 261t283.5 93t283.5 -93t109.5 -261v-352q0 -168 -109.5 -261.5t-283.5 -93.5t-283.5 93.5t-109.5 261.5zM250 1217l188 208l19 11h123l18 -11l188 -208l-4 -15l-112 -37h-15l-137 160l-137 -160h-14l-113 37zM285 365q0 -119 59 -180.5 t170 -61.5q109 0 169 62.5t60 179.5v284q0 117 -60 178.5t-169 61.5q-111 0 -170 -61.5t-59 -178.5v-284z" />
-<glyph unicode="&#xf5;" d="M121 330v352q0 168 109.5 261t283.5 93t283.5 -93t109.5 -261v-352q0 -168 -109.5 -261.5t-283.5 -93.5t-283.5 93.5t-109.5 261.5zM229 1268v14q43 72 86 103.5t109 31.5q61 0 116.5 -47t84.5 -47q31 0 98 68l14 4l74 -56v-14q-78 -135 -199 -135q-59 0 -114.5 46 t-83.5 46q-37 0 -97 -65l-14 -5zM285 365q0 -119 59 -180.5t170 -61.5q109 0 169 62.5t60 179.5v284q0 117 -60 178.5t-169 61.5q-111 0 -170 -61.5t-59 -178.5v-284z" />
-<glyph unicode="&#xf6;" d="M121 330v352q0 168 109.5 261t283.5 93t283.5 -93t109.5 -261v-352q0 -168 -109.5 -261.5t-283.5 -93.5t-283.5 93.5t-109.5 261.5zM285 365q0 -119 59 -180.5t170 -61.5q109 0 169 62.5t60 179.5v284q0 117 -60 178.5t-169 61.5q-111 0 -170 -61.5t-59 -178.5v-284z M295 1260v159l10 11h150l10 -11v-159l-10 -11h-150zM575 1260v159l11 11h149l10 -11v-159l-10 -11h-149z" />
-<glyph unicode="&#xf7;" horiz-adv-x="1126" d="M193 434v141l10 11h733l8 -11l-37 -141l-12 -10h-692zM455 72v192l10 10h188l11 -10v-192l-11 -11h-188zM455 748v192l10 10h188l11 -10v-192l-11 -11h-188z" />
-<glyph unicode="&#xf8;" horiz-adv-x="1038" d="M125 330v352q0 168 109.5 261t283.5 93q119 0 213 -47l55 96l15 5l92 -35l4 -11l-72 -124q86 -96 86 -238v-352q0 -168 -109.5 -261.5t-283.5 -93.5q-117 0 -213 45l-55 -96l-12 -4l-84 49l-4 11l63 110q-88 93 -88 240zM289 365q0 -59 16 -113l348 602q-57 35 -135 35 q-111 0 -170 -61.5t-59 -178.5v-284zM383 156q53 -33 135 -33q109 0 169.5 62.5t60.5 179.5v284q0 57 -17 107z" />
-<glyph unicode="&#xf9;" horiz-adv-x="1060" d="M145 336v653l11 12l143 21l10 -8v-643q0 -127 60.5 -187.5t156.5 -60.5q25 0 77 14.5t93 28.5l39 14v809l10 12l144 21l10 -8v-813l51 -181l-10 -12l-125 -18l-12 8l-60 147q-23 -70 -91 -120t-193 -50q-141 0 -227.5 94.5t-86.5 266.5zM289 1427l10 9h221l15 -9 l122 -208l-2 -13l-102 -41h-12z" />
-<glyph unicode="&#xfa;" horiz-adv-x="1060" d="M145 336v653l11 12l143 21l10 -8v-643q0 -127 60.5 -187.5t156.5 -60.5q25 0 77 14.5t93 28.5l39 14v809l10 12l144 21l10 -8v-813l51 -181l-10 -12l-125 -18l-12 8l-60 147q-23 -70 -91 -120t-193 -50q-141 0 -227.5 94.5t-86.5 266.5zM426 1219l123 208l14 9h221l11 -9 l-252 -262h-13l-102 41z" />
-<glyph unicode="&#xfb;" horiz-adv-x="1060" d="M145 336v653l11 12l143 21l10 -8v-643q0 -127 60.5 -187.5t156.5 -60.5q25 0 77 14.5t93 28.5l39 14v809l10 12l144 21l10 -8v-813l51 -181l-10 -12l-125 -18l-12 8l-60 147q-23 -70 -91 -120t-193 -50q-141 0 -227.5 94.5t-86.5 266.5zM272 1217l189 208l18 11h123 l19 -11l188 -208l-4 -15l-113 -37h-14l-137 160l-138 -160h-14l-113 37z" />
-<glyph unicode="&#xfc;" horiz-adv-x="1060" d="M145 336v653l11 12l143 21l10 -8v-643q0 -127 60.5 -187.5t156.5 -60.5q25 0 77 14.5t93 28.5l39 14v809l10 12l144 21l10 -8v-813l51 -181l-10 -12l-125 -18l-12 8l-60 147q-23 -70 -91 -120t-193 -50q-141 0 -227.5 94.5t-86.5 266.5zM317 1260v159l11 11h149l10 -11 v-159l-10 -11h-149zM598 1260v159l10 11h150l10 -11v-159l-10 -11h-150z" />
-<glyph unicode="&#xfd;" horiz-adv-x="952" d="M-68 -377l62 111l14 4q66 -63 160 -64q123 0 190 187l64 172l-23 8l-16 14l-352 934l10 12l160 21l10 -8l240 -738l30 -108l25 90l233 733l13 10l163 21l7 -10l-428 -1219q-92 -266 -322 -266q-127 0 -235 80zM346 1219l123 208l14 9h222l10 -9l-252 -262h-12l-103 41z " />
-<glyph unicode="&#xfe;" horiz-adv-x="1032" d="M156 -455v1911l10 12l143 21l10 -8v-510l-8 -84q16 31 42 60.5t90.5 59t148.5 29.5q141 0 229 -94t88 -264v-348q0 -168 -104.5 -261.5t-267.5 -93.5q-133 0 -226 72l8 -94v-383l-10 -12l-143 -21zM319 340q0 -217 211 -217q96 0 155.5 63.5t59.5 178.5v278 q0 127 -61 186.5t-160 59.5q-63 0 -205 -47v-502z" />
-<glyph unicode="&#xff;" horiz-adv-x="952" d="M-68 -377l62 111l14 4q66 -63 160 -64q123 0 190 187l64 172l-23 8l-16 14l-352 934l10 12l160 21l10 -8l240 -738l30 -108l25 90l233 733l13 10l163 21l7 -10l-428 -1219q-92 -266 -322 -266q-127 0 -235 80zM238 1260v159l10 11h149l11 -11v-159l-11 -11h-149z M518 1260v159l10 11h150l10 -11v-159l-10 -11h-150z" />
-<glyph unicode="&#x152;" horiz-adv-x="1910" d="M145 477v418q0 244 145.5 376t385.5 132q233 0 375 -141v110l10 10h711l10 -10v-143l-10 -10h-549v-410h477l8 -10l-37 -144l-12 -10h-436v-481h551l8 -10l-21 -144l-12 -10h-688l-10 10v103q-141 -137 -375 -138q-240 0 -385.5 130t-145.5 372zM322 496 q0 -176 100 -266.5t264 -90.5q365 0 365 381v357q0 186 -100.5 274t-264.5 88q-162 0 -263 -93t-101 -265v-385z" />
-<glyph unicode="&#x153;" horiz-adv-x="1599" d="M121 330v352q0 168 109.5 261t283.5 93q209 0 311 -141q100 141 301 141q180 0 265.5 -89t85.5 -214q0 -152 -90.5 -226.5t-239.5 -74.5q-201 0 -250 115l10 -76v-106q0 -117 61.5 -179.5t168.5 -62.5q160 0 223 108l14 5l123 -43l6 -13q-37 -98 -132 -151.5t-226 -53.5 q-219 0 -324 138q-98 -137 -307 -138q-174 0 -283.5 93.5t-109.5 261.5zM285 365q0 -119 59 -180.5t170 -61.5q109 0 169 62.5t60 179.5v284q0 117 -60 178.5t-169 61.5q-111 0 -170 -61.5t-59 -178.5v-284zM907 614q43 -33 215 -32q190 0 191 159q0 61 -47 103.5t-146 42.5 q-213 0 -213 -236v-37z" />
-<glyph unicode="&#x178;" horiz-adv-x="1052" d="M25 1358l10 14l172 23l12 -9l275 -544l32 -80l35 80l260 516l10 12l187 25l12 -9l-418 -780v-596l-10 -10h-151l-11 10v596zM301 1595v160l10 10h150l10 -10v-160l-10 -10h-150zM582 1595v160l10 10h149l11 -10v-160l-11 -10h-149z" />
-<glyph unicode="&#x2c6;" d="M246 1217l188 208l19 11h122l19 -11l188 -208l-4 -15l-112 -37h-15l-137 160l-137 -160h-15l-112 37z" />
-<glyph unicode="&#x2dc;" d="M227 1268v14q43 72 86 103.5t109 31.5q61 0 116.5 -47t84.5 -47q31 0 98 68l14 4l74 -56v-14q-76 -135 -199 -135q-57 0 -114.5 46t-83.5 46q-37 0 -97 -65l-14 -5z" />
-<glyph unicode="&#x2000;" horiz-adv-x="898" />
-<glyph unicode="&#x2001;" horiz-adv-x="1796" />
-<glyph unicode="&#x2002;" horiz-adv-x="898" />
-<glyph unicode="&#x2003;" horiz-adv-x="1796" />
-<glyph unicode="&#x2004;" horiz-adv-x="598" />
-<glyph unicode="&#x2005;" horiz-adv-x="449" />
-<glyph unicode="&#x2006;" horiz-adv-x="299" />
-<glyph unicode="&#x2007;" horiz-adv-x="299" />
-<glyph unicode="&#x2008;" horiz-adv-x="224" />
-<glyph unicode="&#x2009;" horiz-adv-x="359" />
-<glyph unicode="&#x200a;" horiz-adv-x="99" />
-<glyph unicode="&#x2010;" horiz-adv-x="870" d="M170 459v143l10 10h527l8 -10l-37 -143l-12 -10h-486z" />
-<glyph unicode="&#x2011;" horiz-adv-x="870" d="M170 459v143l10 10h527l8 -10l-37 -143l-12 -10h-486z" />
-<glyph unicode="&#x2012;" horiz-adv-x="870" d="M170 459v143l10 10h527l8 -10l-37 -143l-12 -10h-486z" />
-<glyph unicode="&#x2013;" horiz-adv-x="1359" d="M170 465v129l10 10h1008l8 -10l-25 -129l-12 -10h-979z" />
-<glyph unicode="&#x2014;" horiz-adv-x="1765" d="M170 465v129l10 10h1413l9 -10l-25 -129l-12 -10h-1385z" />
-<glyph unicode="&#x2018;" horiz-adv-x="446" d="M82 1022l176 362l14 9l78 -21l8 -14l-59 -336l-14 -10h-197z" />
-<glyph unicode="&#x2019;" horiz-adv-x="415" d="M94 1036l60 336l14 10h197l6 -10l-176 -362l-15 -9l-78 21z" />
-<glyph unicode="&#x201a;" horiz-adv-x="485" d="M86 -154l59 336l15 11h196l6 -11l-176 -362l-14 -8l-78 20z" />
-<glyph unicode="&#x201c;" horiz-adv-x="761" d="M82 1022l176 362l14 9l78 -21l8 -14l-59 -336l-14 -10h-197zM397 1022l176 362l15 9l78 -21l8 -14l-60 -346h-211z" />
-<glyph unicode="&#x201d;" horiz-adv-x="731" d="M94 1036l60 336l14 10h197l6 -10l-176 -362l-15 -9l-78 21zM410 1036l59 336l14 10h197l6 -10l-176 -362l-14 -9l-78 21z" />
-<glyph unicode="&#x201e;" horiz-adv-x="800" d="M88 -152l59 336l15 11h196l7 -11l-177 -362l-14 -8l-78 20zM403 -152l60 336l14 11h197l6 -11l-176 -362l-15 -8l-77 20z" />
-<glyph unicode="&#x2022;" horiz-adv-x="999" d="M152 471v74q0 145 104 227t242 82q139 0 244.5 -82t105.5 -227v-74q0 -147 -104.5 -226t-245.5 -79q-139 0 -242.5 79t-103.5 226z" />
-<glyph unicode="&#x2026;" horiz-adv-x="1617" d="M137 10v193l10 10h189l10 -10v-193l-10 -10h-189zM705 10v193l10 10h188l10 -10v-193l-10 -10h-188zM1272 10v193l10 10h188l11 -10v-193l-11 -10h-188z" />
-<glyph unicode="&#x202f;" horiz-adv-x="359" />
-<glyph unicode="&#x2039;" horiz-adv-x="636" d="M90 500v14l258 389l19 12h153l12 -14l-266 -393l266 -393l-12 -15h-153l-19 13z" />
-<glyph unicode="&#x203a;" horiz-adv-x="636" d="M104 115l267 393l-267 393l13 14h153l19 -12l258 -389v-14l-258 -387l-19 -13h-153z" />
-<glyph unicode="&#x205f;" horiz-adv-x="449" />
-<glyph unicode="&#x20ac;" horiz-adv-x="1214" d="M109 375v123l10 10h129v139h-129l-10 10v123l10 11h135q29 197 167 302t353 105q88 0 166 -20.5t112.5 -40t49.5 -33.5l2 -14l-45 -115l-17 -2q-10 8 -30.5 21.5t-88 35t-141.5 21.5q-139 0 -233 -68t-125 -192h582l8 -11l-33 -123l-12 -10h-557v-139h524l8 -10l-31 -123 l-12 -10h-473q35 -117 129 -179.5t227 -62.5q162 0 279 88l16 -2l41 -115l-2 -14q-14 -14 -50 -35.5t-116 -45.5t-168 -24q-213 0 -354 100.5t-174 289.5h-137z" />
-<glyph unicode="&#x2122;" horiz-adv-x="1607" d="M45 1276v96l10 10h572l8 -10l-27 -96l-12 -10h-199v-535l-10 -10h-106l-11 10v535h-215zM711 731v641l10 10l98 13l15 -11l258 -462l254 450l10 10l100 13l14 -11v-653l-10 -10h-108l-9 10v399l-194 -342l-14 -10h-93l-12 10l-192 351v-408l-11 -10h-106z" />
-<glyph unicode="&#xe000;" horiz-adv-x="1020" d="M0 1020h1020v-1020h-1020v1020z" />
-<glyph unicode="&#xfb01;" horiz-adv-x="1071" d="M63 874v127l11 11h133v215q0 160 109.5 248t261.5 88q166 0 303 -115l2 -14l-90 -103l-17 2q-92 74 -198 74q-88 0 -147.5 -44t-59.5 -128v-223h463l71 10l10 -8v-1004l-10 -10h-143l-10 10v854h-381v-1108l-41 -207l-13 -14l-100 59l-10 19v1251h-133z" />
-<glyph unicode="&#xfb02;" horiz-adv-x="1136" d="M63 874v127l11 11h133v215q0 160 109.5 248t261 88t266.5 -88l92 14l10 -8v-1250q0 -53 29 -72.5t63 -19.5h9l8 -10l-23 -129l-10 -10h-16q-31 0 -61 7t-70.5 27.5t-66.5 70.5t-26 126v1098q-78 88 -204 88q-88 0 -147.5 -44t-59.5 -128v-223h342l10 -11l-39 -127 l-14 -10h-299v-1108l-41 -207l-13 -14l-100 59l-10 19v1251h-133z" />
-<glyph unicode="&#xfb03;" horiz-adv-x="1687" d="M63 874v127l11 11h133v139q0 162 100.5 249t249.5 87q154 0 270 -90q47 80 135.5 123t190.5 43q166 0 303 -115l2 -14l-90 -103l-16 2q-92 74 -199 74q-88 0 -147.5 -44t-59.5 -128v-223h504l72 10l10 -8v-1004l-10 -10h-144l-10 10v854h-422v-1108l-41 -207l-12 -14 l-100 59l-11 19v1251h-411v-1108l-41 -207l-13 -14l-100 59l-10 19v1251h-133zM371 1012h411v205q-10 16 -28.5 37.5t-73.5 49t-123 27.5q-86 0 -136 -43t-50 -129v-147z" />
-<glyph unicode="&#xfb04;" horiz-adv-x="1712" d="M63 874v127l11 11h133v139q0 162 100.5 249t249.5 87q154 0 270 -90q47 80 135.5 123t190.5 43q152 0 266 -88l92 14l11 -8v-1250q0 -53 28.5 -72.5t63.5 -19.5h8l8 -10l-22 -129l-11 -10h-16q-31 0 -60.5 7t-70.5 27.5t-66.5 70.5t-25.5 126v1098q-78 88 -205 88 q-88 0 -147.5 -44t-59.5 -128v-223h311l11 -11l-39 -127l-15 -10h-268v-1108l-41 -207l-12 -14l-100 59l-11 19v1251h-411v-1108l-41 -207l-13 -14l-100 59l-10 19v1251h-133zM371 1012h411v205q-10 16 -28.5 37.5t-73.5 49t-123 27.5q-86 0 -136 -43t-50 -129v-147z" />
-</font>
-</defs></svg> \ No newline at end of file
diff --git a/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.ttf b/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.ttf
deleted file mode 100644
index 6c41e850..00000000
--- a/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.ttf
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.woff b/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.woff
deleted file mode 100644
index ee1153a0..00000000
--- a/openstack_dashboard/static/dashboard/fonts/Anivers_Regular-webfont.woff
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/action_required.png b/openstack_dashboard/static/dashboard/img/action_required.png
deleted file mode 100644
index 071622cb..00000000
--- a/openstack_dashboard/static/dashboard/img/action_required.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/communication_flow.png b/openstack_dashboard/static/dashboard/img/communication_flow.png
deleted file mode 100644
index 44e6b642..00000000
--- a/openstack_dashboard/static/dashboard/img/communication_flow.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/db-gray.gif b/openstack_dashboard/static/dashboard/img/db-gray.gif
deleted file mode 100644
index 7fbeb41a..00000000
--- a/openstack_dashboard/static/dashboard/img/db-gray.gif
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/db-gray.svg b/openstack_dashboard/static/dashboard/img/db-gray.svg
deleted file mode 100644
index 58b3bbad..00000000
--- a/openstack_dashboard/static/dashboard/img/db-gray.svg
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.67 92 92" enable-background="new -3.1 -2.67 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_2_">
- <g>
- <path fill="#FFFFFF" d="M43.33,1.5c23.11,0,41.839,18.73,41.839,41.83c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#808080" stroke-width="3" stroke-miterlimit="10" d="M85.169,43.33c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5C66.44,1.5,85.169,20.23,85.169,43.33z"/>
- </g>
-</g>
-<g id="XMLID_1_">
- <g>
- <path fill="#808080" d="M63.49,52.5v3.99c0,3.75-8.8,6.78-19.67,6.78s-19.67-3.03-19.67-6.78V52.5c0.01,0.01,0.01,0.01,0.02,0.021
- c0.31,3.649,8.98,6.579,19.65,6.579s19.34-2.93,19.65-6.579C63.48,52.51,63.48,52.51,63.49,52.5z"/>
- <path fill="#FFFFFF" d="M63.49,48.33v3.98c0,0.069,0,0.14-0.02,0.21c-2.69,3.239-11.07,5.09-19.65,5.09s-16.96-1.851-19.65-5.09
- c-0.02-0.07-0.02-0.141-0.02-0.21v-3.98c0.04,0.05,0.09,0.11,0.14,0.16c1.27,3.16,9.53,5.63,19.53,5.63
- c9.92,0,18.13-2.43,19.48-5.58C63.37,48.47,63.43,48.4,63.49,48.33z"/>
- <path fill="#FFFFFF" d="M63.49,30.42l-0.03,4.21c-2.72,3-11.119,4.66-19.64,4.66c-8.55,0-16.98-1.67-19.67-4.69v-4.18
- c0.04,0.05,0.09,0.09,0.14,0.14c1.12,2.94,9.43,5.23,19.53,5.23c10.1,0,18.41-2.29,19.53-5.23C63.4,30.51,63.45,30.47,63.49,30.42
- z"/>
- <path fill="#808080" d="M63.49,34.6l-0.03,4.54c-0.029,0.13-0.069,0.26-0.119,0.39c-2.83,3.04-11.091,4.74-19.521,4.74
- c-8.5,0-16.82-1.73-19.59-4.81c-0.03-0.09-0.06-0.19-0.08-0.28v-4.17c0.68,3.2,9.22,5.77,19.67,5.77
- c10.45,0,18.99-2.57,19.64-5.82v-0.33C63.47,34.62,63.48,34.61,63.49,34.6z"/>
- <path fill="#FFFFFF" d="M63.49,39.37l-0.02,4.2c-2.71,3.13-11.09,4.88-19.65,4.88c-8.58,0-16.98-1.76-19.67-4.9v-4.18
- c0.03,0.03,0.05,0.06,0.08,0.09c1.1,3.07,9.44,5.5,19.59,5.5c10.03,0,18.29-2.37,19.521-5.43C63.4,39.48,63.44,39.42,63.49,39.37z
- "/>
- <path fill="#808080" d="M63.49,43.55l-0.02,4.4c-0.03,0.2-0.09,0.39-0.17,0.59c-2.86,3.12-11.07,4.9-19.48,4.9
- c-8.46,0-16.71-1.801-19.53-4.95c-0.07-0.17-0.11-0.34-0.14-0.51V43.8c0.54,3.4,9.14,6.14,19.67,6.14
- c10.53,0,19.13-2.74,19.65-6.17v-0.2C63.48,43.56,63.48,43.56,63.49,43.55z"/>
- <path fill="#808080" d="M63.47,43.57v0.2c-0.521,3.43-9.12,6.17-19.65,6.17c-10.53,0-19.13-2.74-19.67-6.14v-0.25
- c2.69,3.14,11.09,4.9,19.67,4.9C52.38,48.45,60.76,46.7,63.47,43.57z"/>
- <path fill="#808080" d="M63.459,34.63v0.33c-0.649,3.25-9.189,5.82-19.64,5.82c-10.45,0-18.99-2.57-19.67-5.77V34.6
- c2.69,3.02,11.12,4.69,19.67,4.69C52.34,39.29,60.74,37.63,63.459,34.63z"/>
- <path fill="#636464" d="M63.49,29.87c0,0.23-0.04,0.46-0.14,0.69c-2.811,2.93-11.11,4.55-19.53,4.55s-16.72-1.62-19.53-4.55
- c-0.1-0.23-0.14-0.46-0.14-0.69c0-3.27,8.8-5.92,19.67-5.92S63.49,26.6,63.49,29.87z"/>
- <path fill="#636464" d="M63.35,30.56c-1.12,2.94-9.431,5.23-19.53,5.23c-10.1,0-18.41-2.29-19.53-5.23
- c2.81,2.93,11.11,4.55,19.53,4.55S60.54,33.49,63.35,30.56z"/>
- <path fill="#808080" d="M63.47,52.521C63.16,56.17,54.49,59.1,43.82,59.1s-19.34-2.93-19.65-6.579
- c2.69,3.239,11.07,5.09,19.65,5.09S60.78,55.76,63.47,52.521z"/>
- <path fill="#808080" d="M63.3,48.54c-1.351,3.15-9.561,5.58-19.48,5.58c-10,0-18.26-2.47-19.53-5.63
- c2.82,3.149,11.07,4.95,19.53,4.95C52.23,53.44,60.44,51.66,63.3,48.54z"/>
- <path fill="#808080" d="M63.34,39.53c-1.23,3.06-9.49,5.43-19.521,5.43c-10.15,0-18.49-2.43-19.59-5.5
- c2.77,3.08,11.09,4.81,19.59,4.81C52.25,44.27,60.51,42.57,63.34,39.53z"/>
- </g>
- <g>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.35,30.56
- c0.05-0.05,0.1-0.09,0.14-0.14l-0.03,4.21"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.15,34.6v-4.18
- c0.04,0.05,0.09,0.09,0.14,0.14"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.3,48.54
- c0.069-0.07,0.13-0.14,0.189-0.21v3.98c0,0.069,0,0.14-0.02,0.21"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.17,52.521
- c-0.02-0.07-0.02-0.141-0.02-0.21v-3.98c0.04,0.05,0.09,0.11,0.14,0.16"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.15,43.55
- v-4.18c0.03,0.03,0.05,0.06,0.08,0.09"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.34,39.53
- c0.06-0.05,0.1-0.11,0.149-0.16l-0.02,4.2"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.23,39.46
- c-0.03-0.09-0.06-0.19-0.08-0.28v-4.17V34.6c2.69,3.02,11.12,4.69,19.67,4.69c8.521,0,16.92-1.66,19.64-4.66
- c0.011-0.01,0.021-0.02,0.03-0.03l-0.03,4.54c-0.029,0.13-0.069,0.26-0.119,0.39c-1.23,3.06-9.49,5.43-19.521,5.43
- C33.67,44.96,25.33,42.53,24.23,39.46z"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.47,52.521
- c0.01-0.011,0.01-0.011,0.02-0.021v3.99c0,3.75-8.8,6.78-19.67,6.78s-19.67-3.03-19.67-6.78V52.5c0.01,0.01,0.01,0.01,0.02,0.021
- c2.69,3.239,11.07,5.09,19.65,5.09S60.78,55.76,63.47,52.521z"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.47,43.57
- c0.01-0.01,0.01-0.01,0.02-0.02l-0.02,4.4c-0.03,0.2-0.09,0.39-0.17,0.59c-1.351,3.15-9.561,5.58-19.48,5.58
- c-10,0-18.26-2.47-19.53-5.63c-0.07-0.17-0.11-0.34-0.14-0.51V43.8v-0.25c2.69,3.14,11.09,4.9,19.67,4.9
- C52.38,48.45,60.76,46.7,63.47,43.57z"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.29,30.56
- c-0.1-0.23-0.14-0.46-0.14-0.69c0-3.27,8.8-5.92,19.67-5.92s19.67,2.65,19.67,5.92c0,0.23-0.04,0.46-0.14,0.69
- c-1.12,2.94-9.431,5.23-19.53,5.23C33.72,35.79,25.41,33.5,24.29,30.56z"/>
- </g>
-</g>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/db-green.svg b/openstack_dashboard/static/dashboard/img/db-green.svg
deleted file mode 100644
index aea48b9d..00000000
--- a/openstack_dashboard/static/dashboard/img/db-green.svg
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.67 92 92" enable-background="new -3.1 -2.67 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_2_">
- <g>
- <path fill="#FFFFFF" d="M43.33,1.5c23.11,0,41.839,18.73,41.839,41.83c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#186735" stroke-width="3" stroke-miterlimit="10" d="M85.169,43.33c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5C66.44,1.5,85.169,20.23,85.169,43.33z"/>
- </g>
-</g>
-<g id="XMLID_1_">
- <g>
- <path fill="#166734" d="M63.49,52.5v3.99c0,3.75-8.8,6.78-19.67,6.78s-19.67-3.03-19.67-6.78V52.5c0.01,0.01,0.01,0.01,0.02,0.021
- c0.31,3.649,8.98,6.579,19.65,6.579s19.34-2.93,19.65-6.579C63.48,52.51,63.48,52.51,63.49,52.5z"/>
- <path fill="#FFFFFF" d="M63.49,48.33v3.98c0,0.069,0,0.14-0.02,0.21c-2.69,3.239-11.07,5.09-19.65,5.09s-16.96-1.851-19.65-5.09
- c-0.02-0.07-0.02-0.141-0.02-0.21v-3.98c0.04,0.05,0.09,0.11,0.14,0.16c1.27,3.16,9.53,5.63,19.53,5.63
- c9.92,0,18.13-2.43,19.48-5.58C63.37,48.47,63.43,48.4,63.49,48.33z"/>
- <path fill="#FFFFFF" d="M63.49,30.42l-0.03,4.21c-2.72,3-11.119,4.66-19.64,4.66c-8.55,0-16.98-1.67-19.67-4.69v-4.18
- c0.04,0.05,0.09,0.09,0.14,0.14c1.12,2.94,9.43,5.23,19.53,5.23c10.1,0,18.41-2.29,19.53-5.23C63.4,30.51,63.45,30.47,63.49,30.42
- z"/>
- <path fill="#166734" d="M63.49,34.6l-0.03,4.54c-0.029,0.13-0.069,0.26-0.119,0.39c-2.83,3.04-11.091,4.74-19.521,4.74
- c-8.5,0-16.82-1.73-19.59-4.81c-0.03-0.09-0.06-0.19-0.08-0.28v-4.17c0.68,3.2,9.22,5.77,19.67,5.77
- c10.45,0,18.99-2.57,19.64-5.82v-0.33C63.47,34.62,63.48,34.61,63.49,34.6z"/>
- <path fill="#FFFFFF" d="M63.49,39.37l-0.02,4.2c-2.71,3.13-11.09,4.88-19.65,4.88c-8.58,0-16.98-1.76-19.67-4.9v-4.18
- c0.03,0.03,0.05,0.06,0.08,0.09c1.1,3.07,9.44,5.5,19.59,5.5c10.03,0,18.29-2.37,19.521-5.43C63.4,39.48,63.44,39.42,63.49,39.37z
- "/>
- <path fill="#166734" d="M63.49,43.55l-0.02,4.4c-0.03,0.2-0.09,0.39-0.17,0.59c-2.86,3.12-11.07,4.9-19.48,4.9
- c-8.46,0-16.71-1.801-19.53-4.95c-0.07-0.17-0.11-0.34-0.14-0.51V43.8c0.54,3.4,9.14,6.14,19.67,6.14
- c10.53,0,19.13-2.74,19.65-6.17v-0.2C63.48,43.56,63.48,43.56,63.49,43.55z"/>
- <path fill="#0F8140" d="M63.47,43.57v0.2c-0.521,3.43-9.12,6.17-19.65,6.17c-10.53,0-19.13-2.74-19.67-6.14v-0.25
- c2.69,3.14,11.09,4.9,19.67,4.9C52.38,48.45,60.76,46.7,63.47,43.57z"/>
- <path fill="#0F8140" d="M63.459,34.63v0.33c-0.649,3.25-9.189,5.82-19.64,5.82c-10.45,0-18.99-2.57-19.67-5.77V34.6
- c2.69,3.02,11.12,4.69,19.67,4.69C52.34,39.29,60.74,37.63,63.459,34.63z"/>
- <path fill="#1F572B" d="M63.49,29.87c0,0.23-0.04,0.46-0.14,0.69c-2.811,2.93-11.11,4.55-19.53,4.55s-16.72-1.62-19.53-4.55
- c-0.1-0.23-0.14-0.46-0.14-0.69c0-3.27,8.8-5.92,19.67-5.92S63.49,26.6,63.49,29.87z"/>
- <path fill="#0F8140" d="M63.35,30.56c-1.12,2.94-9.431,5.23-19.53,5.23c-10.1,0-18.41-2.29-19.53-5.23
- c2.81,2.93,11.11,4.55,19.53,4.55S60.54,33.49,63.35,30.56z"/>
- <path fill="#0F8140" d="M63.47,52.521C63.16,56.17,54.49,59.1,43.82,59.1s-19.34-2.93-19.65-6.579
- c2.69,3.239,11.07,5.09,19.65,5.09S60.78,55.76,63.47,52.521z"/>
- <path fill="#0F8140" d="M63.3,48.54c-1.351,3.15-9.561,5.58-19.48,5.58c-10,0-18.26-2.47-19.53-5.63
- c2.82,3.149,11.07,4.95,19.53,4.95C52.23,53.44,60.44,51.66,63.3,48.54z"/>
- <path fill="#0F8140" d="M63.34,39.53c-1.23,3.06-9.49,5.43-19.521,5.43c-10.15,0-18.49-2.43-19.59-5.5
- c2.77,3.08,11.09,4.81,19.59,4.81C52.25,44.27,60.51,42.57,63.34,39.53z"/>
- </g>
- <g>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.35,30.56
- c0.05-0.05,0.1-0.09,0.14-0.14l-0.03,4.21"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.15,34.6v-4.18
- c0.04,0.05,0.09,0.09,0.14,0.14"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.3,48.54
- c0.069-0.07,0.13-0.14,0.189-0.21v3.98c0,0.069,0,0.14-0.02,0.21"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.17,52.521
- c-0.02-0.07-0.02-0.141-0.02-0.21v-3.98c0.04,0.05,0.09,0.11,0.14,0.16"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.15,43.55
- v-4.18c0.03,0.03,0.05,0.06,0.08,0.09"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.34,39.53
- c0.06-0.05,0.1-0.11,0.149-0.16l-0.02,4.2"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.23,39.46
- c-0.03-0.09-0.06-0.19-0.08-0.28v-4.17V34.6c2.69,3.02,11.12,4.69,19.67,4.69c8.521,0,16.92-1.66,19.64-4.66
- c0.011-0.01,0.021-0.02,0.03-0.03l-0.03,4.54c-0.029,0.13-0.069,0.26-0.119,0.39c-1.23,3.06-9.49,5.43-19.521,5.43
- C33.67,44.96,25.33,42.53,24.23,39.46z"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.47,52.521
- c0.01-0.011,0.01-0.011,0.02-0.021v3.99c0,3.75-8.8,6.78-19.67,6.78s-19.67-3.03-19.67-6.78V52.5c0.01,0.01,0.01,0.01,0.02,0.021
- c2.69,3.239,11.07,5.09,19.65,5.09S60.78,55.76,63.47,52.521z"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.47,43.57
- c0.01-0.01,0.01-0.01,0.02-0.02l-0.02,4.4c-0.03,0.2-0.09,0.39-0.17,0.59c-1.351,3.15-9.561,5.58-19.48,5.58
- c-10,0-18.26-2.47-19.53-5.63c-0.07-0.17-0.11-0.34-0.14-0.51V43.8v-0.25c2.69,3.14,11.09,4.9,19.67,4.9
- C52.38,48.45,60.76,46.7,63.47,43.57z"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.29,30.56
- c-0.1-0.23-0.14-0.46-0.14-0.69c0-3.27,8.8-5.92,19.67-5.92s19.67,2.65,19.67,5.92c0,0.23-0.04,0.46-0.14,0.69
- c-1.12,2.94-9.431,5.23-19.53,5.23C33.72,35.79,25.41,33.5,24.29,30.56z"/>
- </g>
-</g>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/db-red.svg b/openstack_dashboard/static/dashboard/img/db-red.svg
deleted file mode 100644
index 9154fcd5..00000000
--- a/openstack_dashboard/static/dashboard/img/db-red.svg
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.67 92 92" enable-background="new -3.1 -2.67 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_2_">
- <g>
- <path fill="#FFFFFF" d="M43.33,1.5c23.11,0,41.839,18.73,41.839,41.83c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#C82128" stroke-width="3" stroke-miterlimit="10" d="M85.169,43.33c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5C66.44,1.5,85.169,20.23,85.169,43.33z"/>
- </g>
-</g>
-<g id="XMLID_1_">
- <g>
- <path fill="#C82027" d="M63.49,52.5v3.99c0,3.75-8.8,6.78-19.67,6.78s-19.67-3.03-19.67-6.78V52.5c0.01,0.01,0.01,0.01,0.02,0.021
- c0.31,3.649,8.98,6.579,19.65,6.579s19.34-2.93,19.65-6.579C63.48,52.51,63.48,52.51,63.49,52.5z"/>
- <path fill="#FFFFFF" d="M63.49,48.33v3.98c0,0.069,0,0.14-0.02,0.21c-2.69,3.239-11.07,5.09-19.65,5.09s-16.96-1.851-19.65-5.09
- c-0.02-0.07-0.02-0.141-0.02-0.21v-3.98c0.04,0.05,0.09,0.11,0.14,0.16c1.27,3.16,9.53,5.63,19.53,5.63
- c9.92,0,18.13-2.43,19.48-5.58C63.37,48.47,63.43,48.4,63.49,48.33z"/>
- <path fill="#FFFFFF" d="M63.49,30.42l-0.03,4.21c-2.72,3-11.119,4.66-19.64,4.66c-8.55,0-16.98-1.67-19.67-4.69v-4.18
- c0.04,0.05,0.09,0.09,0.14,0.14c1.12,2.94,9.43,5.23,19.53,5.23c10.1,0,18.41-2.29,19.53-5.23C63.4,30.51,63.45,30.47,63.49,30.42
- z"/>
- <path fill="#C82027" d="M63.49,34.6l-0.03,4.54c-0.029,0.13-0.069,0.26-0.119,0.39c-2.83,3.04-11.091,4.74-19.521,4.74
- c-8.5,0-16.82-1.73-19.59-4.81c-0.03-0.09-0.06-0.19-0.08-0.28v-4.17c0.68,3.2,9.22,5.77,19.67,5.77
- c10.45,0,18.99-2.57,19.64-5.82v-0.33C63.47,34.62,63.48,34.61,63.49,34.6z"/>
- <path fill="#FFFFFF" d="M63.49,39.37l-0.02,4.2c-2.71,3.13-11.09,4.88-19.65,4.88c-8.58,0-16.98-1.76-19.67-4.9v-4.18
- c0.03,0.03,0.05,0.06,0.08,0.09c1.1,3.07,9.44,5.5,19.59,5.5c10.03,0,18.29-2.37,19.521-5.43C63.4,39.48,63.44,39.42,63.49,39.37z
- "/>
- <path fill="#C82027" d="M63.49,43.55l-0.02,4.4c-0.03,0.2-0.09,0.39-0.17,0.59c-2.86,3.12-11.07,4.9-19.48,4.9
- c-8.46,0-16.71-1.801-19.53-4.95c-0.07-0.17-0.11-0.34-0.14-0.51V43.8c0.54,3.4,9.14,6.14,19.67,6.14
- c10.53,0,19.13-2.74,19.65-6.17v-0.2C63.48,43.56,63.48,43.56,63.49,43.55z"/>
- <path fill="#C82027" d="M63.47,43.57v0.2c-0.521,3.43-9.12,6.17-19.65,6.17c-10.53,0-19.13-2.74-19.67-6.14v-0.25
- c2.69,3.14,11.09,4.9,19.67,4.9C52.38,48.45,60.76,46.7,63.47,43.57z"/>
- <path fill="#C82027" d="M63.459,34.63v0.33c-0.649,3.25-9.189,5.82-19.64,5.82c-10.45,0-18.99-2.57-19.67-5.77V34.6
- c2.69,3.02,11.12,4.69,19.67,4.69C52.34,39.29,60.74,37.63,63.459,34.63z"/>
- <path fill="#9F1D20" d="M63.49,29.87c0,0.23-0.04,0.46-0.14,0.69c-2.811,2.93-11.11,4.55-19.53,4.55s-16.72-1.62-19.53-4.55
- c-0.1-0.23-0.14-0.46-0.14-0.69c0-3.27,8.8-5.92,19.67-5.92S63.49,26.6,63.49,29.87z"/>
- <path fill="#9F1D20" d="M63.35,30.56c-1.12,2.94-9.431,5.23-19.53,5.23c-10.1,0-18.41-2.29-19.53-5.23
- c2.81,2.93,11.11,4.55,19.53,4.55S60.54,33.49,63.35,30.56z"/>
- <path fill="#C82027" d="M63.47,52.521C63.16,56.17,54.49,59.1,43.82,59.1s-19.34-2.93-19.65-6.579
- c2.69,3.239,11.07,5.09,19.65,5.09S60.78,55.76,63.47,52.521z"/>
- <path fill="#C82027" d="M63.3,48.54c-1.351,3.15-9.561,5.58-19.48,5.58c-10,0-18.26-2.47-19.53-5.63
- c2.82,3.149,11.07,4.95,19.53,4.95C52.23,53.44,60.44,51.66,63.3,48.54z"/>
- <path fill="#C82027" d="M63.34,39.53c-1.23,3.06-9.49,5.43-19.521,5.43c-10.15,0-18.49-2.43-19.59-5.5
- c2.77,3.08,11.09,4.81,19.59,4.81C52.25,44.27,60.51,42.57,63.34,39.53z"/>
- </g>
- <g>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.35,30.56
- c0.05-0.05,0.1-0.09,0.14-0.14l-0.03,4.21"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.15,34.6v-4.18
- c0.04,0.05,0.09,0.09,0.14,0.14"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.3,48.54
- c0.069-0.07,0.13-0.14,0.189-0.21v3.98c0,0.069,0,0.14-0.02,0.21"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.17,52.521
- c-0.02-0.07-0.02-0.141-0.02-0.21v-3.98c0.04,0.05,0.09,0.11,0.14,0.16"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.15,43.55
- v-4.18c0.03,0.03,0.05,0.06,0.08,0.09"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.34,39.53
- c0.06-0.05,0.1-0.11,0.149-0.16l-0.02,4.2"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.23,39.46
- c-0.03-0.09-0.06-0.19-0.08-0.28v-4.17V34.6c2.69,3.02,11.12,4.69,19.67,4.69c8.521,0,16.92-1.66,19.64-4.66
- c0.011-0.01,0.021-0.02,0.03-0.03l-0.03,4.54c-0.029,0.13-0.069,0.26-0.119,0.39c-1.23,3.06-9.49,5.43-19.521,5.43
- C33.67,44.96,25.33,42.53,24.23,39.46z"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.47,52.521
- c0.01-0.011,0.01-0.011,0.02-0.021v3.99c0,3.75-8.8,6.78-19.67,6.78s-19.67-3.03-19.67-6.78V52.5c0.01,0.01,0.01,0.01,0.02,0.021
- c2.69,3.239,11.07,5.09,19.65,5.09S60.78,55.76,63.47,52.521z"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M63.47,43.57
- c0.01-0.01,0.01-0.01,0.02-0.02l-0.02,4.4c-0.03,0.2-0.09,0.39-0.17,0.59c-1.351,3.15-9.561,5.58-19.48,5.58
- c-10,0-18.26-2.47-19.53-5.63c-0.07-0.17-0.11-0.34-0.14-0.51V43.8v-0.25c2.69,3.14,11.09,4.9,19.67,4.9
- C52.38,48.45,60.76,46.7,63.47,43.57z"/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="square" stroke-linejoin="round" stroke-miterlimit="10" d="M24.29,30.56
- c-0.1-0.23-0.14-0.46-0.14-0.69c0-3.27,8.8-5.92,19.67-5.92s19.67,2.65,19.67,5.92c0,0.23-0.04,0.46-0.14,0.69
- c-1.12,2.94-9.431,5.23-19.53,5.23C33.72,35.79,25.41,33.5,24.29,30.56z"/>
- </g>
-</g>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/drag.png b/openstack_dashboard/static/dashboard/img/drag.png
deleted file mode 100644
index bd67b9fc..00000000
--- a/openstack_dashboard/static/dashboard/img/drag.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/drop_arrow.png b/openstack_dashboard/static/dashboard/img/drop_arrow.png
deleted file mode 100644
index e2e83000..00000000
--- a/openstack_dashboard/static/dashboard/img/drop_arrow.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/favicon.ico b/openstack_dashboard/static/dashboard/img/favicon.ico
deleted file mode 100644
index f3b9bf9c..00000000
--- a/openstack_dashboard/static/dashboard/img/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/horizontal_loader.gif b/openstack_dashboard/static/dashboard/img/horizontal_loader.gif
deleted file mode 100644
index f2d08339..00000000
--- a/openstack_dashboard/static/dashboard/img/horizontal_loader.gif
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/lb-gray.gif b/openstack_dashboard/static/dashboard/img/lb-gray.gif
deleted file mode 100644
index 9b1c5162..00000000
--- a/openstack_dashboard/static/dashboard/img/lb-gray.gif
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/lb-gray.svg b/openstack_dashboard/static/dashboard/img/lb-gray.svg
deleted file mode 100644
index eb858750..00000000
--- a/openstack_dashboard/static/dashboard/img/lb-gray.svg
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.67 92 92" enable-background="new -3.1 -2.67 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_3_">
- <g>
- <path fill="#FFFFFF" d="M43.33,1.5c23.11,0,41.839,18.73,41.839,41.83c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#808080" stroke-width="3" stroke-miterlimit="10" d="M85.169,43.33c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5C66.44,1.5,85.169,20.23,85.169,43.33z"/>
- </g>
-</g>
-<g id="XMLID_2_">
- <g>
- <path fill="#808080" d="M68.8,41.85v12.52H18.83V41.92c0-0.02,0.01-0.04,0.02-0.07H68.79C68.79,41.88,68.8,41.83,68.8,41.85z
- M55.31,48.36c0-1.11-0.9-2-2-2c-1.11,0-2,0.89-2,2c0,1.109,0.89,2,2,2C54.41,50.36,55.31,49.47,55.31,48.36z M46.31,48.36
- c0-1.11-0.891-2-1.99-2c-1.11,0-2,0.89-2,2c0,1.109,0.89,2,2,2C45.419,50.36,46.31,49.47,46.31,48.36z M37.32,48.36
- c0-1.11-0.89-2-2-2c-1.1,0-2,0.89-2,2c0,1.109,0.9,2,2,2C36.43,50.36,37.32,49.47,37.32,48.36z"/>
- <polygon fill="#636464" points="61.82,32.33 68.79,41.85 18.85,41.85 25.81,32.33 "/>
- <path fill="#FFFFFF" d="M53.31,46.36c1.1,0,2,0.89,2,2c0,1.109-0.9,2-2,2c-1.11,0-2-0.891-2-2C51.31,47.25,52.2,46.36,53.31,46.36
- z"/>
- <path fill="#FFFFFF" d="M44.32,46.36c1.1,0,1.99,0.89,1.99,2c0,1.109-0.891,2-1.99,2c-1.11,0-2-0.891-2-2
- C42.32,47.25,43.21,46.36,44.32,46.36z"/>
- <path fill="#FFFFFF" d="M35.32,46.36c1.11,0,2,0.89,2,2c0,1.109-0.89,2-2,2c-1.1,0-2-0.891-2-2
- C33.32,47.25,34.22,46.36,35.32,46.36z"/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 68.79,41.85 61.82,32.33 25.81,32.33 18.85,41.85 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M18.85,41.85
- c-0.01,0.03-0.02,0.05-0.02,0.07v12.45H68.8V41.85c0-0.02-0.011,0.03-0.011,0H18.85z"/>
- </g>
-</g>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/lb-green.svg b/openstack_dashboard/static/dashboard/img/lb-green.svg
deleted file mode 100644
index 770ffc79..00000000
--- a/openstack_dashboard/static/dashboard/img/lb-green.svg
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.67 92 92" enable-background="new -3.1 -2.67 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_3_">
- <g>
- <path fill="#FFFFFF" d="M43.33,1.5c23.11,0,41.839,18.73,41.839,41.83c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#156734" stroke-width="3" stroke-miterlimit="10" d="M85.169,43.33c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5C66.44,1.5,85.169,20.23,85.169,43.33z"/>
- </g>
-</g>
-<g id="XMLID_2_">
- <g>
- <path fill="#166734" d="M18.85,41.85H68.79c0,0.03,0.011-0.02,0.011,0v12.52H18.83V41.92C18.83,41.9,18.84,41.88,18.85,41.85z
- M55.31,48.36c0-1.11-0.9-2-2-2c-1.11,0-2,0.89-2,2c0,1.109,0.89,2,2,2C54.41,50.36,55.31,49.47,55.31,48.36z M46.31,48.36
- c0-1.11-0.891-2-1.99-2c-1.11,0-2,0.89-2,2c0,1.109,0.89,2,2,2C45.419,50.36,46.31,49.47,46.31,48.36z M37.32,48.36
- c0-1.11-0.89-2-2-2c-1.1,0-2,0.89-2,2c0,1.109,0.9,2,2,2C36.43,50.36,37.32,49.47,37.32,48.36z"/>
- <path fill="#FFFFFF" d="M53.31,46.36c1.1,0,2,0.89,2,2c0,1.109-0.9,2-2,2c-1.11,0-2-0.891-2-2C51.31,47.25,52.2,46.36,53.31,46.36
- z"/>
- <path fill="#FFFFFF" d="M44.32,46.36c1.1,0,1.99,0.89,1.99,2c0,1.109-0.891,2-1.99,2c-1.11,0-2-0.891-2-2
- C42.32,47.25,43.21,46.36,44.32,46.36z"/>
- <path fill="#FFFFFF" d="M35.32,46.36c1.11,0,2,0.89,2,2c0,1.109-0.89,2-2,2c-1.1,0-2-0.891-2-2
- C33.32,47.25,34.22,46.36,35.32,46.36z"/>
- <polygon fill="#1F572B" points="18.85,41.85 25.81,32.33 61.82,32.33 68.79,41.85 "/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 68.79,41.85 61.82,32.33 25.81,32.33 18.85,41.85 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M18.85,41.85
- c-0.01,0.03-0.02,0.05-0.02,0.07v12.45H68.8V41.85c0-0.02-0.011,0.03-0.011,0H18.85z"/>
- </g>
-</g>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/lb-red.svg b/openstack_dashboard/static/dashboard/img/lb-red.svg
deleted file mode 100644
index 12434fd1..00000000
--- a/openstack_dashboard/static/dashboard/img/lb-red.svg
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.67 92 92" enable-background="new -3.1 -2.67 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_3_">
- <g>
- <path fill="#FFFFFF" d="M43.33,1.5c23.11,0,41.839,18.73,41.839,41.83c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#C82128" stroke-width="3" stroke-miterlimit="10" d="M85.169,43.33c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5C66.44,1.5,85.169,20.23,85.169,43.33z"/>
- </g>
-</g>
-<g id="XMLID_2_">
- <g>
- <path fill="#C82027" d="M18.85,41.85H68.79c0,0.03,0.011-0.02,0.011,0v12.52H18.83V41.92C18.83,41.9,18.84,41.88,18.85,41.85z
- M55.31,48.36c0-1.11-0.9-2-2-2c-1.11,0-2,0.89-2,2c0,1.109,0.89,2,2,2C54.41,50.36,55.31,49.47,55.31,48.36z M46.31,48.36
- c0-1.11-0.891-2-1.99-2c-1.11,0-2,0.89-2,2c0,1.109,0.89,2,2,2C45.419,50.36,46.31,49.47,46.31,48.36z M37.32,48.36
- c0-1.11-0.89-2-2-2c-1.1,0-2,0.89-2,2c0,1.109,0.9,2,2,2C36.43,50.36,37.32,49.47,37.32,48.36z"/>
- <path fill="#FFFFFF" d="M53.31,46.36c1.1,0,2,0.89,2,2c0,1.109-0.9,2-2,2c-1.11,0-2-0.891-2-2C51.31,47.25,52.2,46.36,53.31,46.36
- z"/>
- <path fill="#FFFFFF" d="M44.32,46.36c1.1,0,1.99,0.89,1.99,2c0,1.109-0.891,2-1.99,2c-1.11,0-2-0.891-2-2
- C42.32,47.25,43.21,46.36,44.32,46.36z"/>
- <path fill="#FFFFFF" d="M35.32,46.36c1.11,0,2,0.89,2,2c0,1.109-0.89,2-2,2c-1.1,0-2-0.891-2-2
- C33.32,47.25,34.22,46.36,35.32,46.36z"/>
- <polygon fill="#9F1D20" points="18.85,41.85 25.81,32.33 61.82,32.33 68.79,41.85 "/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 68.79,41.85 61.82,32.33 25.81,32.33 18.85,41.85 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M18.85,41.85
- c-0.01,0.03-0.02,0.05-0.02,0.07v12.45H68.8V41.85c0-0.02-0.011,0.03-0.011,0H18.85z"/>
- </g>
-</g>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/loading.gif b/openstack_dashboard/static/dashboard/img/loading.gif
deleted file mode 100644
index 3890f094..00000000
--- a/openstack_dashboard/static/dashboard/img/loading.gif
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/logo-splash.png b/openstack_dashboard/static/dashboard/img/logo-splash.png
deleted file mode 100644
index 87a988a1..00000000
--- a/openstack_dashboard/static/dashboard/img/logo-splash.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/logo.png b/openstack_dashboard/static/dashboard/img/logo.png
deleted file mode 100644
index 87a988a1..00000000
--- a/openstack_dashboard/static/dashboard/img/logo.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/right_droparrow.png b/openstack_dashboard/static/dashboard/img/right_droparrow.png
deleted file mode 100644
index d585fb2b..00000000
--- a/openstack_dashboard/static/dashboard/img/right_droparrow.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/router.png b/openstack_dashboard/static/dashboard/img/router.png
deleted file mode 100644
index fd701b53..00000000
--- a/openstack_dashboard/static/dashboard/img/router.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/search.png b/openstack_dashboard/static/dashboard/img/search.png
deleted file mode 100644
index 27670da8..00000000
--- a/openstack_dashboard/static/dashboard/img/search.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/server-gray.gif b/openstack_dashboard/static/dashboard/img/server-gray.gif
deleted file mode 100644
index 7f411c0d..00000000
--- a/openstack_dashboard/static/dashboard/img/server-gray.gif
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/server-gray.svg b/openstack_dashboard/static/dashboard/img/server-gray.svg
deleted file mode 100644
index 9e17b0bd..00000000
--- a/openstack_dashboard/static/dashboard/img/server-gray.svg
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.7 92 92" enable-background="new -3.1 -2.7 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_3_">
- <g>
- <path fill="#FFFFFF" d="M43.3,1.5c23.1,0,41.8,18.7,41.8,41.8c0,23.1-18.7,41.8-41.8,41.8c-23.1,0-41.8-18.7-41.8-41.8
- C1.5,20.2,20.2,1.5,43.3,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#808080" stroke-width="3" stroke-miterlimit="10" d="M85.2,43.3c0,23.1-18.7,41.8-41.8,41.8
- c-23.1,0-41.8-18.7-41.8-41.8c0-23.1,18.7-41.8,41.8-41.8C66.4,1.5,85.2,20.2,85.2,43.3z"/>
- </g>
-</g>
-<g id="XMLID_1_">
- <g>
- <path fill="#808080" d="M68.6,42.4V55H39v-2.8h2V45v-2.6H68.6C68.5,42.5,68.6,42.4,68.6,42.4z M63,48.7c0-1.2-0.9-2.1-2-2.1
- c-1.1,0-2,0.9-2,2.1c0,1.1,0.9,2.1,2,2.1C62.2,50.8,63,49.8,63,48.7z"/>
- <polygon fill="#636464" points="61.6,33 68.5,42.4 41,42.4 18.5,42.4 25.5,33 "/>
- <path fill="#FFFFFF" d="M61,46.6c1.1,0,2,0.9,2,2.1c0,1.1-0.9,2.1-2,2.1c-1.1,0-2-0.9-2-2.1C59,47.5,59.9,46.6,61,46.6z"/>
- <rect x="39" y="45" fill="#808080" width="2" height="7.3"/>
- <path fill="#808080" d="M41,42.4V45h-2v7.3V55H18.5V42.5c0,0,0,0,0-0.1H41z M36,52.2V45h-2v7.3H36z M31,52.2V45h-2v7.3H31z
- M26,52.2V45h-2v7.3H26z"/>
- <rect x="34" y="45" fill="#808080" width="2" height="7.3"/>
- <rect x="29" y="45" fill="#808080" width="2" height="7.3"/>
- <rect x="24" y="45" fill="#808080" width="2" height="7.3"/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 68.5,42.4 61.6,33 25.5,33 18.5,42.4 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M39,55h29.5V42.4
- c0,0,0,0,0,0H41H18.5c0,0,0,0.1,0,0.1V55H39z"/>
-
- <rect x="24" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="29" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="34" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="39" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
- </g>
-</g>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/server-green.svg b/openstack_dashboard/static/dashboard/img/server-green.svg
deleted file mode 100644
index 52ac168c..00000000
--- a/openstack_dashboard/static/dashboard/img/server-green.svg
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.7 92 92" enable-background="new -3.1 -2.7 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_3_">
- <g>
- <path fill="#FFFFFF" d="M43.3,1.5c23.1,0,41.8,18.7,41.8,41.8c0,23.1-18.7,41.8-41.8,41.8c-23.1,0-41.8-18.7-41.8-41.8
- C1.5,20.2,20.2,1.5,43.3,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#156734" stroke-width="3" stroke-miterlimit="10" d="M85.2,43.3c0,23.1-18.7,41.8-41.8,41.8
- c-23.1,0-41.8-18.7-41.8-41.8c0-23.1,18.7-41.8,41.8-41.8C66.4,1.5,85.2,20.2,85.2,43.3z"/>
- </g>
-</g>
-<g id="XMLID_1_">
- <g>
- <polygon fill="#0F8140" points="61.6,33 68.5,42.4 41,42.4 18.5,42.4 25.5,33 "/>
- <path fill="#FFFFFF" d="M61,46.6c1.1,0,2,0.9,2,2.1c0,1.1-0.9,2.1-2,2.1c-1.1,0-2-0.9-2-2.1C59,47.5,59.9,46.6,61,46.6z"/>
- <path fill="#156734" d="M63,48.7c0-1.2-0.9-2.1-2-2.1c-1.1,0-2,0.9-2,2.1c0,1.1,0.9,2.1,2,2.1C62.2,50.8,63,49.8,63,48.7z
- M68.6,42.4V55H39v-2.8h2V45v-2.6H68.6C68.5,42.5,68.6,42.4,68.6,42.4z"/>
- <rect x="39" y="45" fill="#156734" width="2" height="7.3"/>
- <rect x="34" y="45" fill="#156734" width="2" height="7.3"/>
- <rect x="29" y="45" fill="#156734" width="2" height="7.3"/>
- <rect x="24" y="45" fill="#156734" width="2" height="7.3"/>
- <path fill="#156734" d="M24,52.2h2V45h-2V52.2z M29,52.2h2V45h-2V52.2z M18.5,42.4H41V45h-2v7.3V55H18.5L18.5,42.4
- C18.5,42.5,18.5,42.5,18.5,42.4z M34,45v7.3h2V45H34z"/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 68.5,42.4 61.6,33 25.5,33 18.5,42.4 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M39,55h29.5V42.4
- c0,0,0,0,0,0H41H18.5c0,0,0,0.1,0,0.1V55H39z"/>
-
- <rect x="24" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="29" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="34" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="39" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
- </g>
-</g>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/server-red.svg b/openstack_dashboard/static/dashboard/img/server-red.svg
deleted file mode 100644
index ecce52df..00000000
--- a/openstack_dashboard/static/dashboard/img/server-red.svg
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.7 92 92" enable-background="new -3.1 -2.7 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_3_">
- <g>
- <path fill="#FFFFFF" d="M43.3,1.5c23.1,0,41.8,18.7,41.8,41.8c0,23.1-18.7,41.8-41.8,41.8c-23.1,0-41.8-18.7-41.8-41.8
- C1.5,20.2,20.2,1.5,43.3,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#C82027" stroke-width="3" stroke-miterlimit="10" d="M85.2,43.3c0,23.1-18.7,41.8-41.8,41.8
- c-23.1,0-41.8-18.7-41.8-41.8c0-23.1,18.7-41.8,41.8-41.8C66.4,1.5,85.2,20.2,85.2,43.3z"/>
- </g>
-</g>
-<g id="XMLID_1_">
- <g>
- <path fill="#C82027" d="M68.6,42.4V55H39v-2.8h2V45v-2.6H68.6C68.5,42.5,68.6,42.4,68.6,42.4z M63,48.7c0-1.2-0.9-2.1-2-2.1
- c-1.1,0-2,0.9-2,2.1c0,1.1,0.9,2.1,2,2.1C62.2,50.8,63,49.8,63,48.7z"/>
- <polygon fill="#9F1D20" points="61.6,33 68.5,42.4 41,42.4 18.5,42.4 25.5,33 "/>
- <path fill="#FFFFFF" d="M61,46.6c1.1,0,2,0.9,2,2.1c0,1.1-0.9,2.1-2,2.1c-1.1,0-2-0.9-2-2.1C59,47.5,59.9,46.6,61,46.6z"/>
- <rect x="39" y="45" fill="#C82027" width="2" height="7.3"/>
- <path fill="#C82027" d="M41,42.4V45h-2v7.3V55H18.5V42.5c0,0,0,0,0-0.1H41z M36,52.2V45h-2v7.3H36z M31,52.2V45h-2v7.3H31z
- M26,52.2V45h-2v7.3H26z"/>
- <rect x="34" y="45" fill="#C82027" width="2" height="7.3"/>
- <rect x="29" y="45" fill="#C82027" width="2" height="7.3"/>
- <rect x="24" y="45" fill="#C82027" width="2" height="7.3"/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 68.5,42.4 61.6,33 25.5,33 18.5,42.4 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M39,55h29.5V42.4
- c0,0,0,0,0,0H41H18.5c0,0,0,0.1,0,0.1V55H39z"/>
-
- <rect x="24" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="29" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="34" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="39" y="45" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
- </g>
-</g>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/server.png b/openstack_dashboard/static/dashboard/img/server.png
deleted file mode 100644
index 08c5d66e..00000000
--- a/openstack_dashboard/static/dashboard/img/server.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/stack-gray.gif b/openstack_dashboard/static/dashboard/img/stack-gray.gif
deleted file mode 100644
index 54a2cee4..00000000
--- a/openstack_dashboard/static/dashboard/img/stack-gray.gif
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/stack-gray.svg b/openstack_dashboard/static/dashboard/img/stack-gray.svg
deleted file mode 100644
index 71134ee3..00000000
--- a/openstack_dashboard/static/dashboard/img/stack-gray.svg
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.7 92 92" enable-background="new -3.1 -2.7 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<circle fill="#FFFFFF" stroke="#808080" stroke-width="3" stroke-miterlimit="10" cx="43.3" cy="43.3" r="41.8"/>
-<g id="XMLID_6_">
- <g>
- <path fill="#808080" d="M68.5,51.9v12.6h-50V52c0,0,0,0,0-0.1H68.5C68.5,52,68.5,51.9,68.5,51.9z"/>
- <polygon fill="#0F8140" points="61.6,42.5 68.5,51.9 18.5,51.9 25.5,42.5 "/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 68.5,51.9 61.6,42.5 25.5,42.5 18.5,51.9 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M18.5,51.9
- C18.5,52,18.5,52,18.5,51.9l0,12.6h50V51.9c0,0,0,0,0,0H18.5z"/>
- <line fill="none" stroke="#FFFFFF" stroke-miterlimit="10" x1="27" y1="55.5" x2="60" y2="55.5"/>
- <line fill="none" stroke="#FFFFFF" stroke-miterlimit="10" x1="27" y1="58.5" x2="60" y2="58.5"/>
- <line fill="none" stroke="#FFFFFF" stroke-miterlimit="10" x1="27" y1="61.5" x2="60" y2="61.5"/>
- </g>
-</g>
-<g id="XMLID_5_">
- <g>
- <path fill="#808080" d="M68.5,39.4V52H39v-2.8h2V42v-2.6H68.5C68.5,39.5,68.5,39.4,68.5,39.4z M63,45.7c0-1.2-0.9-2.1-2-2.1
- c-1.1,0-2,0.9-2,2.1c0,1.1,0.9,2.1,2,2.1C62.1,47.8,63,46.8,63,45.7z"/>
- <polygon fill="#0F8140" points="61.6,30 68.5,39.4 41,39.4 18.5,39.4 25.5,30 "/>
- <path fill="#FFFFFF" d="M61,43.6c1.1,0,2,0.9,2,2.1c0,1.1-0.9,2.1-2,2.1c-1.1,0-2-0.9-2-2.1C59,44.5,59.9,43.6,61,43.6z"/>
- <rect x="39" y="42" fill="#808080" width="2" height="7.3"/>
- <path fill="#808080" d="M41,39.4V42h-2v7.3V52H18.5V39.5c0,0,0,0,0-0.1H41z M36,49.3V42h-2v7.3H36z M31,49.3V42h-2v7.3H31z
- M26,49.3V42h-2v7.3H26z"/>
- <rect x="34" y="42" fill="#808080" width="2" height="7.3"/>
- <rect x="29" y="42" fill="#808080" width="2" height="7.3"/>
- <rect x="24" y="42" fill="#808080" width="2" height="7.3"/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 68.5,39.4 61.6,30 25.5,30 18.5,39.4 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M39,52h29.5V39.4
- c0,0,0,0,0,0H41H18.5c0,0,0,0.1,0,0.1V52H39z"/>
-
- <rect x="24" y="42" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="29" y="42" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="34" y="42" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="39" y="42" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
- </g>
-</g>
-<g id="XMLID_4_">
- <g>
- <path fill="#808080" d="M68.5,27v12.5h-50V27.1c0,0,0,0,0-0.1H68.5C68.5,27,68.5,27,68.5,27z M55,33.5c0-1.1-0.9-2-2-2
- c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2C54.1,35.5,55,34.6,55,33.5z M46,33.5c0-1.1-0.9-2-2-2c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2
- C45.1,35.5,46,34.6,46,33.5z M37,33.5c0-1.1-0.9-2-2-2c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2C36.1,35.5,37,34.6,37,33.5z"/>
- <polygon fill="#636565" points="61.5,17.5 68.5,27 18.5,27 25.5,17.5 "/>
- <path fill="#FFFFFF" d="M53,31.5c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C51,32.4,51.9,31.5,53,31.5z"/>
- <path fill="#FFFFFF" d="M44,31.5c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C42,32.4,42.9,31.5,44,31.5z"/>
- <path fill="#FFFFFF" d="M35,31.5c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C33,32.4,33.9,31.5,35,31.5z"/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="68.5,27
- 61.5,17.5 25.5,17.5 18.5,27 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M18.5,27
- C18.5,27,18.5,27.1,18.5,27l0,12.5h50V27c0,0,0,0,0,0H18.5z"/>
- </g>
-</g>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/stack-green.svg b/openstack_dashboard/static/dashboard/img/stack-green.svg
deleted file mode 100644
index 3faac892..00000000
--- a/openstack_dashboard/static/dashboard/img/stack-green.svg
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.7 92 92" enable-background="new -3.1 -2.7 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_8_">
- <g>
- <path fill="#FFFFFF" d="M43.3,1.5c23.1,0,41.8,18.7,41.8,41.8c0,23.1-18.7,41.8-41.8,41.8c-23.1,0-41.8-18.7-41.8-41.8
- C1.5,20.2,20.2,1.5,43.3,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#156734" stroke-width="3" stroke-miterlimit="10" d="M85.2,43.3c0,23.1-18.7,41.8-41.8,41.8
- c-23.1,0-41.8-18.7-41.8-41.8c0-23.1,18.7-41.8,41.8-41.8C66.4,1.5,85.2,20.2,85.2,43.3z"/>
- </g>
-</g>
-<g id="XMLID_7_">
- <g>
- <polygon fill="#0F8140" points="68.5,51.9 18.5,51.9 25.5,42.5 61.6,42.5 "/>
- <path fill="#156734" d="M68.6,64.5h-50V52c0,0,0,0,0-0.1h50c0,0,0,0,0,0V64.5z"/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 68.5,51.9 61.6,42.5 25.5,42.5 18.5,51.9 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M18.5,51.9
- C18.5,52,18.5,52,18.5,51.9l0,12.6h50V51.9c0,0,0,0,0,0H18.5z"/>
- <line fill="none" stroke="#FFFFFF" stroke-miterlimit="10" x1="27" y1="55.5" x2="60" y2="55.5"/>
- <line fill="none" stroke="#FFFFFF" stroke-miterlimit="10" x1="27" y1="58.5" x2="60" y2="58.5"/>
- <line fill="none" stroke="#FFFFFF" stroke-miterlimit="10" x1="27" y1="61.5" x2="60" y2="61.5"/>
- </g>
-</g>
-<g id="XMLID_6_">
- <g>
- <polygon fill="#0F8140" points="61.6,30 68.5,39.4 41,39.4 18.5,39.4 25.5,30 "/>
- <path fill="#FFFFFF" d="M61,43.6c1.1,0,2,0.9,2,2.1c0,1.1-0.9,2.1-2,2.1c-1.1,0-2-0.9-2-2.1C59,44.5,59.9,43.6,61,43.6z"/>
- <path fill="#156734" d="M63,45.7c0-1.2-0.9-2.1-2-2.1c-1.1,0-2,0.9-2,2.1c0,1.1,0.9,2.1,2,2.1C62.2,47.8,63,46.8,63,45.7z
- M68.6,39.4V52H39v-2.8h2V42v-2.6H68.6C68.5,39.5,68.6,39.4,68.6,39.4z"/>
- <rect x="39" y="42" fill="#156734" width="2" height="7.3"/>
- <rect x="34" y="42" fill="#156734" width="2" height="7.3"/>
- <rect x="29" y="42" fill="#156734" width="2" height="7.3"/>
- <rect x="24" y="42" fill="#156734" width="2" height="7.3"/>
- <path fill="#156734" d="M24,49.2h2V42h-2V49.2z M29,49.2h2V42h-2V49.2z M18.5,39.4H41V42h-2v7.3V52H18.5L18.5,39.4
- C18.5,39.5,18.5,39.5,18.5,39.4z M34,42v7.3h2V42H34z"/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 68.5,39.4 61.6,30 25.5,30 18.5,39.4 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M39,52h29.5V39.4
- c0,0,0,0,0,0H41H18.5c0,0,0,0.1,0,0.1V52H39z"/>
-
- <rect x="24" y="42" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="29" y="42" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="34" y="42" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
-
- <rect x="39" y="42" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.3"/>
- </g>
-</g>
-<g id="XMLID_5_">
- <g>
- <path fill="#156734" d="M68.5,27v12.5h-50V27.1c0,0,0,0,0-0.1H68.5C68.5,27,68.5,27,68.5,27z M55,33.5c0-1.1-0.9-2-2-2
- c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2C54.1,35.5,55,34.6,55,33.5z M46,33.5c0-1.1-0.9-2-2-2c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2
- C45.1,35.5,46,34.6,46,33.5z M37,33.5c0-1.1-0.9-2-2-2c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2C36.1,35.5,37,34.6,37,33.5z"/>
- <polygon fill="#1E572B" points="61.5,17.5 68.5,27 18.5,27 25.5,17.5 "/>
- <path fill="#FFFFFF" d="M53,31.5c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C51,32.4,51.9,31.5,53,31.5z"/>
- <path fill="#FFFFFF" d="M44,31.5c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C42,32.4,42.9,31.5,44,31.5z"/>
- <path fill="#FFFFFF" d="M35,31.5c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C33,32.4,33.9,31.5,35,31.5z"/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="68.5,27
- 61.5,17.5 25.5,17.5 18.5,27 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M18.5,27
- C18.5,27,18.5,27.1,18.5,27l0,12.5h50V27c0,0,0,0,0,0H18.5z"/>
- </g>
-</g>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/stack-red.svg b/openstack_dashboard/static/dashboard/img/stack-red.svg
deleted file mode 100644
index 14bf3cd8..00000000
--- a/openstack_dashboard/static/dashboard/img/stack-red.svg
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
- width="90.5px" height="91px" viewBox="49 -16.5 90.5 91" enable-background="new 49 -16.5 90.5 91" xml:space="preserve">
-<title>Compute</title>
-<g>
- <circle fill="#FFFFFF" stroke="#C90505" stroke-width="3" stroke-miterlimit="10" cx="93.934" cy="29.499" r="41.833"/>
- <g>
- <g>
- <g id="XMLID_3_">
- <g>
- <path fill="#C90505" d="M119.15,50.666h-50.04v-12.5c0-0.01,0.01-0.04,0.01-0.08h50.01c0.01,0.04,0.02-0.02,0.02,0V50.666z"/>
- <polygon fill="#008000" points="112.161,28.666 119.131,38.086 69.121,38.086 76.101,28.666 "/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 119.131,38.086 112.161,28.666 76.101,28.666 69.121,38.086 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M69.121,38.086
- c0,0.04-0.01,0.07-0.01,0.08v12.5h50.04v-12.58c0-0.02-0.01,0.04-0.02,0H69.121z"/>
- <line fill="none" stroke="#FFFFFF" stroke-miterlimit="10" x1="77.61" y1="41.666" x2="110.641" y2="41.666"/>
- <line fill="none" stroke="#FFFFFF" stroke-miterlimit="10" x1="77.61" y1="44.666" x2="110.641" y2="44.666"/>
- <line fill="none" stroke="#FFFFFF" stroke-miterlimit="10" x1="77.61" y1="47.666" x2="110.641" y2="47.666"/>
- </g>
- </g>
- </g>
- <g>
- <title>Compute</title>
- <g>
- <g id="XMLID_2_">
- <g>
- <path fill="#C90505" d="M119.15,25.596v12.57H89.61v-2.75h2v-7.25v-2.57h27.521C119.141,25.626,119.15,25.576,119.15,25.596z
- M113.641,31.866c0-1.16-0.89-2.101-2-2.101c-1.1,0-2,0.94-2,2.101c0,1.149,0.9,2.09,2,2.09
- C112.751,33.956,113.641,33.016,113.641,31.866z"/>
- <polygon fill="#008000" points="112.161,16.166 119.131,25.596 91.61,25.596 69.121,25.596 76.101,16.166 "/>
- <path fill="#FFFFFF" d="M111.641,29.766c1.11,0,2,0.94,2,2.101c0,1.149-0.89,2.09-2,2.09c-1.1,0-2-0.94-2-2.09
- C109.641,30.706,110.541,29.766,111.641,29.766z"/>
- <rect x="89.61" y="28.166" fill="#C90505" width="2" height="7.25"/>
- <rect x="84.61" y="28.166" fill="#C90505" width="2" height="7.25"/>
- <rect x="79.61" y="28.166" fill="#C90505" width="2" height="7.25"/>
- <rect x="74.611" y="28.166" fill="#C90505" width="2" height="7.25"/>
- <path fill="#C90505" d="M74.611,35.416h2v-7.25h-2V35.416z M79.61,35.416h2v-7.25h-2V35.416z M84.61,35.416h2v-7.25h-2V35.416
- z M89.61,28.166v7.25v2.75h-20.5v-12.49c0-0.02,0.01-0.05,0.01-0.08h22.49v2.57H89.61z"/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 119.131,25.596 112.161,16.166 76.101,16.166 69.121,25.596 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M89.61,38.166
- h29.54v-12.57c0-0.02-0.01,0.03-0.02,0H91.61h-22.49c0,0.03-0.01,0.061-0.01,0.08v12.49H89.61z"/>
-
- <rect x="74.611" y="28.166" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.25"/>
-
- <rect x="79.61" y="28.166" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.25"/>
-
- <rect x="84.61" y="28.166" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.25"/>
-
- <rect x="89.61" y="28.166" fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" width="2" height="7.25"/>
- </g>
- </g>
- </g>
- </g>
- <g>
- <title>Load Balancer</title>
- <g>
- <g id="XMLID_1_">
- <g>
- <path fill="#C90505" d="M119.081,13.186v12.52h-49.97v-12.45c0-0.02,0.01-0.04,0.02-0.07h49.939
- C119.07,13.216,119.081,13.166,119.081,13.186z M105.591,19.696c0-1.11-0.9-2-2-2c-1.11,0-2,0.89-2,2c0,1.11,0.89,2,2,2
- C104.69,21.696,105.591,20.806,105.591,19.696z M96.591,19.696c0-1.11-0.891-2-1.99-2c-1.11,0-2,0.89-2,2c0,1.11,0.89,2,2,2
- C95.7,21.696,96.591,20.806,96.591,19.696z M87.601,19.696c0-1.11-0.89-2-2-2c-1.1,0-2,0.89-2,2c0,1.11,0.9,2,2,2
- C86.711,21.696,87.601,20.806,87.601,19.696z"/>
- <polygon fill="#A00202" points="112.101,3.666 119.07,13.186 69.131,13.186 76.091,3.666 "/>
- <path fill="#FFFFFF" d="M103.591,17.696c1.1,0,2,0.89,2,2c0,1.11-0.9,2-2,2c-1.11,0-2-0.89-2-2
- C101.591,18.586,102.48,17.696,103.591,17.696z"/>
- <path fill="#FFFFFF" d="M94.601,17.696c1.1,0,1.99,0.89,1.99,2c0,1.11-0.891,2-1.99,2c-1.11,0-2-0.89-2-2
- C92.601,18.586,93.49,17.696,94.601,17.696z"/>
- <path fill="#FFFFFF" d="M85.601,17.696c1.11,0,2,0.89,2,2c0,1.11-0.89,2-2,2c-1.1,0-2-0.89-2-2
- C83.601,18.586,84.501,17.696,85.601,17.696z"/>
- </g>
- <g>
- <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points="
- 119.07,13.186 112.101,3.666 76.091,3.666 69.131,13.186 "/>
- <path fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M69.131,13.186
- c-0.01,0.03-0.02,0.05-0.02,0.07v12.45h49.97v-12.52c0-0.02-0.011,0.03-0.011,0H69.131z"/>
- </g>
- </g>
- </g>
- </g>
- </g>
-</g>
-<line fill="none" x1="41" y1="42.25" x2="90.969" y2="42.25"/>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/unknown-gray.gif b/openstack_dashboard/static/dashboard/img/unknown-gray.gif
deleted file mode 100644
index c90d8d8a..00000000
--- a/openstack_dashboard/static/dashboard/img/unknown-gray.gif
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/img/unknown-green.svg b/openstack_dashboard/static/dashboard/img/unknown-green.svg
deleted file mode 100644
index a619d05d..00000000
--- a/openstack_dashboard/static/dashboard/img/unknown-green.svg
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.67 92 92" enable-background="new -3.1 -2.67 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_1_">
- <g>
- <path fill="#FFFFFF" d="M43.33,1.5c23.11,0,41.839,18.73,41.839,41.83c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#186735" stroke-width="3" stroke-miterlimit="10" d="M85.169,43.33c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5C66.44,1.5,85.169,20.23,85.169,43.33z"/>
- </g>
-</g>
-<rect x="26.899" y="28.166" fill="none" stroke="#186735" stroke-miterlimit="10" width="13.333" height="13.333"/>
-<rect x="40.232" y="40.966" fill="none" stroke="#186735" stroke-miterlimit="10" width="13.334" height="13.333"/>
-<rect x="26.899" y="40.966" fill="#21572C" stroke="#186735" stroke-miterlimit="10" width="13.334" height="13.333"/>
-<rect x="40.232" y="28.166" fill="#21572C" stroke="#186735" stroke-miterlimit="10" width="13.334" height="13.333"/>
-<rect x="46.634" y="35.5" fill="#FFFFFF" stroke="#186735" stroke-miterlimit="10" width="13.332" height="13.334"/>
-<rect x="33.833" y="48.832" fill="#FFFFFF" stroke="#186735" stroke-miterlimit="10" width="13.334" height="13.334"/>
-<rect x="33.833" y="35.5" fill="#21572C" stroke="#186735" stroke-miterlimit="10" width="13.334" height="13.334"/>
-<rect x="46.634" y="48.832" fill="#21572C" stroke="#186735" stroke-miterlimit="10" width="13.332" height="13.334"/>
-<line fill="none" stroke="#186735" stroke-miterlimit="10" x1="33.833" y1="62.166" x2="26.899" y2="54.299"/>
-<line fill="none" stroke="#186735" stroke-miterlimit="10" x1="33.833" y1="35.5" x2="26.899" y2="28.166"/>
-<line fill="none" stroke="#186735" stroke-miterlimit="10" x1="59.966" y1="35.5" x2="53.566" y2="28.166"/>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/unknown-red.svg b/openstack_dashboard/static/dashboard/img/unknown-red.svg
deleted file mode 100644
index 90fd38db..00000000
--- a/openstack_dashboard/static/dashboard/img/unknown-red.svg
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In -->
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
-]>
-<svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
- x="0px" y="0px" width="92px" height="92px" viewBox="-3.1 -2.67 92 92" enable-background="new -3.1 -2.67 92 92"
- xml:space="preserve">
-<defs>
-</defs>
-<g id="XMLID_1_">
- <g>
- <path fill="#FFFFFF" d="M43.33,1.5c23.11,0,41.839,18.73,41.839,41.83c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5z"/>
- </g>
- <g>
- <path fill="none" stroke="#C82128" stroke-width="3" stroke-miterlimit="10" d="M85.169,43.33c0,23.1-18.729,41.83-41.839,41.83
- c-23.1,0-41.83-18.73-41.83-41.83C1.5,20.23,20.23,1.5,43.33,1.5C66.44,1.5,85.169,20.23,85.169,43.33z"/>
- </g>
-</g>
-<rect x="26.899" y="28.166" fill="none" stroke="#C82128" stroke-miterlimit="10" width="13.333" height="13.333"/>
-<rect x="40.232" y="40.966" fill="none" stroke="#186735" stroke-miterlimit="10" width="13.334" height="13.333"/>
-<rect x="26.899" y="40.966" fill="#9F1E22" stroke="#C82128" stroke-miterlimit="10" width="13.334" height="13.333"/>
-<rect x="40.232" y="28.166" fill="#9F1E22" stroke="#C82128" stroke-miterlimit="10" width="13.334" height="13.333"/>
-<rect x="46.634" y="35.5" fill="#FFFFFF" stroke="#C82128" stroke-miterlimit="10" width="13.332" height="13.334"/>
-<rect x="33.833" y="48.832" fill="#FFFFFF" stroke="#C82128" stroke-miterlimit="10" width="13.334" height="13.334"/>
-<rect x="33.833" y="35.5" fill="#9F1E22" stroke="#C82128" stroke-miterlimit="10" width="13.334" height="13.334"/>
-<rect x="46.634" y="48.832" fill="#9F1E22" stroke="#C82128" stroke-miterlimit="10" width="13.332" height="13.334"/>
-<line fill="none" stroke="#C82128" stroke-miterlimit="10" x1="33.833" y1="62.166" x2="26.899" y2="54.299"/>
-<line fill="none" stroke="#C82128" stroke-miterlimit="10" x1="33.833" y1="35.5" x2="26.899" y2="28.166"/>
-<line fill="none" stroke="#C82128" stroke-miterlimit="10" x1="59.966" y1="35.5" x2="53.566" y2="28.166"/>
-</svg>
diff --git a/openstack_dashboard/static/dashboard/img/up_arrow.png b/openstack_dashboard/static/dashboard/img/up_arrow.png
deleted file mode 100644
index 0f6e50fc..00000000
--- a/openstack_dashboard/static/dashboard/img/up_arrow.png
+++ /dev/null
Binary files differ
diff --git a/openstack_dashboard/static/dashboard/less/horizon.less b/openstack_dashboard/static/dashboard/less/horizon.less
deleted file mode 100644
index 3a97df0f..00000000
--- a/openstack_dashboard/static/dashboard/less/horizon.less
+++ /dev/null
@@ -1,2122 +0,0 @@
-@import "../../bootstrap/less/bootstrap.less";
-@import "../../bootstrap/less/datepicker.less";
-
-/* new clearfix */
-.clearfix:after {
- visibility: hidden;
- display: block;
- font-size: 0;
- content: " ";
- clear: both;
- height: 0;
- }
-* html .clearfix { zoom: 1; } /* IE6 */
-*:first-child+html .clearfix { zoom: 1; } /* IE7 */
-
-@font-face {
- font-family: 'anivers';
- src: url('/static/dashboard/fonts/Anivers_Regular-webfont.eot');
- src: url('/static/dashboard/fonts/Anivers_Regular-webfont.eot?iefix') format('eot'),
- url('/static/dashboard/fonts/Anivers_Regular-webfont.woff') format('woff'),
- url('/static/dashboard/fonts/Anivers_Regular-webfont.ttf') format('truetype'),
- url('/static/dashboard/fonts/Anivers_Regular-webfont.svg#webfont3JLVF59W') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-
-a {
- color: #43a1d6;
-}
-
-ul {
- list-style: none;
- margin: 0;
-}
-
-dt {
- font-weight: bold;
-}
-
-#main_content {
- padding-left: 250px;
- padding-right: 25px;
-}
-
-.topbar {
- background: #f2f2f2;
- border-bottom: 1px solid #e5e5e5;
- padding: 10px 25px;
- margin-top: 0;
- margin-left: -25px;
- margin-bottom: 20px;
- margin-right: -25px;
- min-width: 700px;
-}
-
-.topbar .switcher_bar {
- display: inline-block;
- height: auto;
- width: 160px;
- background-position: 140px center;
- margin-bottom: 0;
- font-size: 11px;
- margin-left: 20px;
- padding: 0;
- background-image: url(/static/dashboard/img/drop_arrow.png);
- border: 1px solid #c0d9e4;
- background-color: #e9f5fa;
- background-repeat: no-repeat;
-}
-
-.topbar .switcher_bar a {
- padding: 2px 10px 1px;
- margin-left: 0;
- display: block;
-}
-
-.topbar .switcher_bar ul {
- width: 130px;
-}
-
-#user_info {
- color: #888;
- margin: auto 0;
-}
-
-#user_info > a {
- margin-left: 25px;
- font-size: 11px !important;
-}
-
-.page-header {
- margin: 0;
- padding: 0;
- border: 0;
- font-family: anivers;
-}
-
-h2 {
- color: #6a6a6a;
- font-size: 30px;
- font-weight: normal;
-}
-
-body {
- background-color: #fff;
- min-width: 890px;
-}
-
-/* Login Splash Page */
-
-#splash {
- background: #fafafa;
-}
-
-#splash .login {
- background: #fff url(/static/dashboard/img/logo-splash.png) no-repeat center 35px;
- position: absolute;
- top: 80px;
- left: 50%;
- margin: 0 0 0 -195px;
- padding-top: 170px;
- width: 390px;
- border: 1px solid #e1e1e1;
- max-height: none;
- -webkit-border-radius: 6px;
- -moz-border-radius: 6px;
- border-radius: 6px;
- -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
- -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
- box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
- -webkit-background-clip: padding-box;
- -moz-background-clip: padding-box;
- background-clip: padding-box;
-
- form {
- .error {
- width: 100%;
- }
- input {
- width: 350px;
- }
- select {
- width: 360px;
- }
- }
-}
-
-#splash .help-block {
- display: none;
-}
-
-#create_container_form .modal-footer{
- margin-top: 190px;
-}
-
-.nav li a {
- color: #8EACB7;
- text-shadow: none;
-}
-
-.container-fluid {
- padding-left: 0;
-}
-
-.sidebar {
- background: #edf9ff;
- border-right: 5px solid #e5e5e5;
- border-bottom: 5px solid #e5e5e5;
- float: left;
-}
-
-.sidebar h4 {
- margin-left: 14px;
- color: #999;
-}
-
-.sidebar .nav-tabs {
- margin-top: -34px;
-}
-
-.sidebar .nav-tabs li.active a {
- background-color: #edf9ff;
-}
-
-h1.brand {
- width: 100%;
- margin: 0;
- background-color: #f5f5f5;
- padding-bottom: 40px;
-}
-
-h1.brand a {
- background: url(/static/dashboard/img/logo.png) top left no-repeat;
- display: block;
- float: left;
- width: 116px;
- height: 123px;
- text-indent: -9999px;
- margin-left: 56px;
- margin-top: 15px;
- margin-bottom: 25px;
-}
-
-
-/* Tenant Dropdown */
-
-
-a.current_item {
- width: 163px;
- float: left;
-}
-
-a.current_item:hover {
- text-decoration: none;
-}
-
-a.current_item:hover h3, a.current_item:hover h4 {
- color: #39738c;
-}
-
-.sidebar .switcher_bar {
- width: 190px;
- height: 38px;
- padding: 5px 0;
- margin-left: 14px;
- margin-bottom: 15px;
-}
-
-.sidebar .switcher_bar a.dropdown-toggle {
- display: block;
- padding: 5px 0;
- background-image: url(/static/dashboard/img/drop_arrow.png);
- border: 1px solid #c0d9e4;
- background-color: #e9f5fa;
- background-repeat: no-repeat;
- background-position: 167px 23px;
-}
-
-.sidebar .switcher_bar a.dropdown-toggle:hover {
- text-decoration: none;
- background-color: #cde8f4;
-}
-
-.sidebar .switcher_bar:focus {
- outline: none;
-}
-
-.sidebar .switcher_bar h3 {
- color: #4790ae;
- font-size: 16px;
- margin: -6px 0 0 14px;
- padding: 0;
- overflow: hidden;
- text-overflow:ellipsis;
- white-space: nowrap;
- &:hover {
- white-space: normal;
- overflow: visible;
- text-overflow: none;
- padding-right: 1em;
- word-wrap: break-word;
- }
-}
-
-.sidebar .switcher_bar h4 {
- color: #6fabc4;
- font-size: 10px;
- text-transform: uppercase;
- font-weight: normal;
- padding: 0;
-}
-
-
-.sidebar .switcher_bar ul {
- border: 1px solid #c0d9e4;
- margin-left: -1px;
- width: 190px;
-}
-
-.sidebar .switcher_bar li a:hover{
- background: #92d6f1;
-}
-
-
-#usage {
- margin-bottom: 25px;
- height: 125px;
-}
-
-.usage_block {
- background: #e8f8ff;
- color: #84b6c5;
- border: 1px solid #afe3fb;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- border-radius: 5px;
- float: left;
- width: 29%;
- margin-right: 5%;
- min-height: 125px;
-}
-
-.usage_block.last {
- margin-right: 0;
-}
-
-
-.usage_block h3 {
- background: #cef0ff;
- color: #4fa5bf;
- font-weight: normal;
- padding: 0 0 0 10px;
- border-bottom: 1px solid #c6e7f5;
- -webkit-border-top-left-radius: 5px;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topleft: 5px;
- -moz-border-radius-topright: 5px;
- border-top-left-radius: 5px;
- border-top-right-radius: 5px;
-}
-.usage_block ul {
- margin: 10px;
-}
-
-.usage_block .quantity { font-size: 25px; }
-
-.usage_block li {
- font-size: 11px;
- margin: 0 0 15px 0;
-}
-
-.usage_block .unit{
- font-size: 11px;
- text-transform: uppercase;
- padding: 0 0 0 1px;
-}
-
-
-.table-bordered {
- border: none;
-}
-.table_header {
- min-height: 35px;
- padding: 5px 0;
-}
-.table_caption th {
- background-color: transparent;
- border: none;
-}
-.table-bordered tr.table_caption + tr th {
- border-top: 1px solid #ddd;
-}
-.table-bordered tr.table_caption + tr th:first-child,
-.table-bordered tr.table_caption + tr th.hide + th {
- -moz-border-radius-topleft: 4px;
- -webkit-border-top-left-radius: 4px;
- border-top-left-radius: 4px;
- border-left: 1px solid #ddd;
-}
-.table-bordered tr.table_caption + tr th:last-child {
- -moz-border-radius-topright: 4px;
- -webkit-border-top-right-radius: 4px;
- border-top-right-radius: 4px;
- border-right: 1px solid #ddd;
-}
-.table-bordered tbody tr td:first-child,
-.table-bordered tfoot tr td:first-child {
- border-left: 1px solid #ddd;
-}
-.table-bordered tbody tr td:last-child,
-.table-bordered tfoot tr td:last-child {
- border-right: 1px solid #ddd;
-}
-.table-bordered tfoot tr td:first-child {
- border-bottom: 1px solid #ddd;
- -moz-border-radius-bottomleft: 4px;
- -webkit-border-bottom-left-radius: 4px;
- border-bottom-left-radius: 4px;
-}
-.table-bordered tfoot tr td:last-child {
- border-bottom: 1px solid #ddd;
- -moz-border-radius-bottomright: 4px;
- -webkit-border-bottom-right-radius: 4px;
- border-bottom-right-radius: 4px;
-}
-.table_title h3, .table_header h3 {
- font-family: anivers;
- font-weight: normal;
- font-size: 24px;
- margin-bottom: 5px;
- float: left;
-}
-.table th.header {
- cursor: pointer;
-}
-.table th.header:hover {
- background-color: #e8e8e8;
- text-decoration: underline;
-}
-.table tbody td.anchor a {
- display: block;
- padding: 8px;
-}
-.table tr.table_caption th.header:hover {
- background-color: transparent;
- cursor: default;
-}
-.table th.headerSortUp:hover,
-.table th.headerSortDown:hover {
- background-color: #dfdfdf;
-}
-.table th.headerSortUp,
-.table th.headerSortDown {
- background-color: #dfdfdf;
- background-repeat: no-repeat;
- background-position: 98% center;
-}
-.table th.headerSortDown {
- background-image: url(/static/dashboard/img/drop_arrow.png);
-}
-.table th.headerSortUp {
- background-image: url(/static/dashboard/img/up_arrow.png);
-}
-.table tr.summation td:first-child,
-.table tr.summation td:last-child {
- border-radius: 0;
- border-bottom: 0 none;
-}
-
-th {
- background: #f1f1f1;
-}
-td.anchor {
- padding: 0;
-}
-
-
-small {
- font-size: 11px;
-}
-
-.main_nav {
- list-style: none;
- width: 222px;
- margin: 10px 0 20px 0;
-}
-
-.main_nav a {
- color: #999;
- width: 185px;
- padding: 10px;
- display: block;
- margin-left: 20px;
-}
-
-.main_nav a.active {
- background: #fff;
- border: 2px solid #d8d8d8;
- border-right: 0;
- border-bottom-color: #ccc;
-}
-
-table form {
- margin-bottom: 0;
- width: 1px;
-}
-
-.messages {
- position: fixed;
- z-index: 9999;
- top: 20px;
- right: 20px;
- width: 300px;
- .alert-block {
- -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
- -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
- box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
- &.alert-error {
- border: 1px solid @red;
- }
- &.alert-success {
- border: 1px solid @green;
- }
- }
-}
-
-.alert-block .alert-actions {
- margin-top: -23px;
- margin-right: -23px;
-}
-
-.modal > form,
-.login > form,
-.alert-actions > form {
- margin-bottom: 0;
-}
-
-.alert-block p {
- overflow: hidden;
- word-wrap: break-word;
-}
-
-.alert-block p:last-child {
- margin-bottom: 0;
-}
-
-#actions.single {
- width: 90px;
-}
-
-.table-striped tr td {
- transition: background 0.2s;
- -webkit-transition: background 0.2s;
- -moz-transition: background 0.2s;
- -o-transition: background 0.2s;
-}
-
-.inspect {
- float: left;
- display: block;
- margin-top: 5px;
- margin-right: 25px;
-}
-
-.table {
- margin-bottom: 25px;
-}
-
-.table tr td {
- vertical-align: middle;
-}
-
-.table tr.empty td {
- text-align: center;
-}
-
-.table tfoot tr td {
- border-top: 1px solid #DDD;
- background-color: #F1F1F1;
- font-size: 11px;
- line-height: 14px;
-}
-
-.table_actions {
- float: right;
- min-width: 400px;
-}
-
-.table_actions .table_search, .table_actions .table_filter {
- display: inline-block;
-}
-
-.table_search input {
- background: url(/static/dashboard/img/search.png) no-repeat 195px 5px;
- display: inline-block;
- margin-bottom: 0;
-}
-
-.table_actions a, .table_actions button {
- float: right;
- margin-left: 10px;
-}
-
-.table_actions button.filter {
- margin-left: 0;
-}
-
-.table_actions {
- .btn-icon(@x, @y, @icons: "/static/bootstrap/img/glyphicons-halflings.png") {
- padding-left: 23px;
- position: relative;
-
- &:before {
- display: inline-block;
- content: "";
- width: 18px;
- height: 20px;
- margin-top: 1px;
- *margin-right: .3em;
- line-height: 14px;
- background-image: url(@icons);
- background-position: @x @y;
- background-repeat: no-repeat;
- position: absolute;
- top: 0px;
- left: 0px;
- }
- }
-
- .btn-icon-danger(@x, @y) {
- .btn-icon(@x, @y, "/static/bootstrap/img/glyphicons-halflings-white.png");
- }
-
- a.btn-create, a.btn-launch {
- .btn-icon(-403px, -92px);
- }
-
- a.btn-download {
- .btn-icon(-91px, -19px);
- }
-
- a.btn-upload {
- .btn-icon(-283px, -92px);
- }
-
- button.btn-delete, button.btn-terminate {
- .btn-icon-danger(-451px, 5px);
- }
-
-}
-
-.table_header .table_actions {
- min-width: 0;
-}
-
-.table_header .table_actions a, .table_header .table_actions > button,
-.table_header .table_actions .table_search button {
- display: inline-block;
- float: none;
-}
-
-.table_header .table_filter {
- vertical-align: bottom;
- margin-right: 20px;
-}
-
-.table_header .table_filter i {
- vertical-align: middle;
-}
-
-.table_actions form {
- float: right;
- margin-left: 10px;
-}
-
-.hidden {
- display: none;
-}
-
-/*
- * Bootstrap styles table backgrounds using nth-child(2n+1), which is
- * oblivious to hidden elements. The styles below allow us to override
- * the bootstrap style when neccessary by setting the odd/even classes.
- */
-.table-striped.datatable tbody {
- tr.odd td {
- background-color: #f9f9f9;
- }
- tr.even td {
- background-color: inherit;
- }
- tr.odd:hover td,
- tr.even:hover td,
- tr:hover th {
- background-color: #f5f5f5;
- }
-}
-
-.table-striped tbody tr.status_unknown:nth-child(odd) td {
- background-color: #ffffb5;
-}
-
-.table-striped tbody tr.status_unknown:nth-child(even) td {
- background-color: #ffffc6;
-}
-
-.nowrap-col {
- white-space: nowrap;
-}
-
-.overview {
- font-size: 24px;
-}
-
-#monitoring {
- background: #f8f8f8;
- font-size: 14px;
- height: 20px;
- margin: -18px 0 25px;
- padding: 10px;
- border: 1px solid #e1e1e1;
- font-family: "anivers";
-}
-
-#monitoring h3 {
- font-size: 14px;
- font-weight: normal;
- float: left;
- line-height: 18px;
-}
-
-#external_links, #external_links li {
- float: left;
-}
-#external_links li { margin: 0 0 0 15px; }
-
-/* Forms */
-
-form label {
- text-align: left;
- color: #555;
- font-weight: bold;
-}
-
-.modal {
- width: 700px;
- max-height: none; /* Prevents large modals from scrolling unnecessarily */
- top: 80px;
- margin-top: 0;
- position: absolute;
-}
-
-.modal.loading {
- width: 150px;
- height: 150px;
- margin: 0 auto;
- overflow: hidden;
-}
-
-.modal.loading p {
- text-align: center;
- position: absolute;
- bottom: 0;
- width: 150px;
-}
-
-.datepicker {
- margin-top: 10px;
-}
-
-.datepicker input {
- width: 65px;
- margin-right: 10px;
-}
-
-.datepicker .btn {
- margin-right: 10px;
-}
-
-form.horizontal .form-field {
- float: left;
- }
-
-form.horizontal.split_half .form-field {
- width: 334px; /* Fits 2 fields to a row */
-}
-
-form.horizontal.split_quarter .form-field {
- width: 167px; /* Fits 4 fields to a row */
-}
-
-form.horizontal.split_five .form-field {
- width: 133px; /* Fits 5 fields to a row */
-}
-
-form.horizontal fieldset {
- width: 100%;
-}
-
-.modal-body {
- overflow-y: visible;
- max-height: none;
-}
-
-.modal-body table {
- margin-bottom: 30px;
-}
-
-.modal-body ~ hr {
- margin-bottom: 0;
-}
-
-.static_page {
- float: left;
- width: 700px;
- background-color: #FFF;
- border: 1px solid #DDD;
-}
-.static_page > form {
- margin-bottom: 0;
-}
-
-.left {
- float: left;
- width: 347px;
- margin-right: 15px;
-}
-
-.left form {
- margin: 0;
-}
-
-.right {
- float: left;
- width: 308px;
-}
-
-.workflow ul.nav-tabs {
- padding: 0 10px;
-}
-
-.workflow td.actions {
- vertical-align: top;
- width: 308px;
- padding-right: 10px;
-}
-
-.workflow td.help_text {
- vertical-align: top;
- width: 340px;
- padding-left: 10px;
- border-left: 1px solid #DDD;
-}
-
-.workflow fieldset > table {
- margin-bottom: 0;
-}
-
-.clear {
- clear: both;
- width: 0;
- height: 0;
- padding: 0;
- margin: 0;
-}
-
-.modal-body fieldset {
- margin: 0;
- padding: 0;
-}
-
-.modal-body fieldset ul {
- width: 90%;
-}
-
-.modal-body fieldset .form-field input,
-.modal-body fieldset .form-field textarea {
- width: 298px;
-}
-.modal-body fieldset .form-field select {
- width: 308px;
-}
-.modal-body fieldset .form-field textarea {
- height: @baseLineHeight * 2;
-}
-
-.modal-footer input {
- width: auto;
-}
-
-.modal-body .modal-footer {
- width: 670px;
- margin-left: -25px;
- margin-right: -15px;
-}
-
-.modal-footer a.close {
- margin-top: 0;
- margin-right: 5px;
- font-size: 12px;
- color: #666;
- font-weight: normal;
- filter: alpha(opacity=100);
- -khtml-opacity: 1;
- -moz-opacity: 1;
- opacity: 1;
-}
-
-.modal-footer a.close:hover {
- color: #333;
- text-decoration: underline;
-}
-
-.modal-body .help-block {
- text-align: left;
- float: left;
- width: 100%;
- margin-bottom: 10px;
-}
-
-#create_keypair_modal .clearfix {
- margin-bottom: 115px;
-}
-
-#actions {
- width: 90px;
-}
-#actions .btn {
- margin-bottom: 5px;
-}
-#actions a.btn {
- width: 70px;
-}
-
-#actions input.btn {
- text-align: left;
-}
-
-#images #actions {
- width: 100px;
-}
-
-/*New List Patches*/
-.details-modal .modal-body {
- padding-bottom: 20px;
-}
-
-.form-inline {
- display: inline;
- input, button, a.btn {
- margin-left: 5px;
- }
-}
-
-td.select {
- width: 10px;
-}
-
-/* Actions dropdown */
-
-td.actions_column {
- white-space: nowrap;
- padding: 10px;
- position: relative;
- width: 200px;
-}
-
-td.actions_column .btn-group {
- display: inline-block;
-}
-
-td.actions_column .row_actions a,
-td.actions_column .row_actions input,
-td.actions_column .row_actions button {
- background: none;
- float: none;
- display: block;
- padding: 5px 10px;
- color: black;
- text-align: left;
- border-radius: 0;
- border: 0 none;
- -webkit-box-shadow: none;
- -moz-box-shadow: none;
- box-shadow: none;
-}
-
-td.actions_column .row_actions .hide {
- display: none;
-}
-
-td.actions_column .btn-action-required {
- font-weight: bold;
-}
-
-.tab-content {
- overflow: visible;
-}
-
-/* Makes size consistent across browsers when mixing "btn-group" and "small" */
-.btn.hide, .btn-group .hide {
- display: none;
-}
-.btn-group .dropdown-toggle:focus {
- outline: none;
-}
-.dropdown-menu button {
- line-height: 18px; /* Matches rule for ".dropdown-menu a" in bootstrap */
- width: 100%;
-}
-.btn-group .dropdown-menu .btn {
- border-radius: 0;
-}
-.dropdown-menu .btn.btn-danger,
-.dropdown-menu .btn.btn-danger:hover,
-.dropdown-menu .btn.btn-success,
-.dropdown-menu .btn.btn-success:hover,
-.dropdown-menu .btn.btn-info,
-.dropdown-menu .btn.btn-info:hover {
- text-shadow: none; /* remove default bootstrap shadowing from button text. */
-}
-.dropdown-menu li:hover {
- background: none;
-}
-.dropdown-menu li.divider:hover {
- background-color: #E5E5E5;
-}
-
-td.actions_column .dropdown-menu a:hover,
-td.actions_column .dropdown-menu button:hover {
- background-color: #CDCDCD;
-}
-.dropdown-menu .btn.btn-danger {
- color: #C43C35;
-}
-.dropdown-menu .btn.btn-danger:hover {
- background-color: #f6e0df;
-}
-
-
-/* Overrides for single-action rows (no dropdown) */
-
-tr td.actions_column ul.row_actions.single,
-tr:hover td.actions_column ul.row_actions.single,
-td.actions_column ul.row_actions.single,
-td.actions_column ul.row_actions.single:hover {
- border: none;
-}
-
-td.actions_column ul.row_actions.single li.action {
- display: block;
-}
-
-td.actions_column ul.row_actions.single li.action:hover {
- background-color: transparent;
-}
-
-td.actions_column ul.row_actions.single a,
-td.actions_column ul.row_actions.single input,
-td.actions_column ul.row_actions.single button {
- color: #43a1d6;
-}
-
-td.actions_column ul.row_actions.single a:hover,
-td.actions_column ul.row_actions.single input:hover,
-td.actions_column ul.row_actions.single button:hover {
- color: black;
-}
-
-th.multi_select_column, td.multi_select_column {
- width: 25px;
-}
-
-th.multi_select_column, td.multi_select_column {
- text-align: center;
-}
-
-.table-fixed {
- table-layout: fixed;
-}
-
-.table input[type="checkbox"] {
- display: inline;
-}
-
-div.input input[type="checkbox"] {
- float: left;
- width: 25px;
-}
-
-.table_title a {
- font-size: 11px;
- float: right;
- margin-left: 10px;
- margin-top: 10px;
-}
-
-tr.terminated {
- color: #999999;
-}
-
-#instance_tabs {
- float: left;
- width: 100%;
- border-bottom: 1px solid #e1e1e1;
-}
-
-#instance_tabs li a {
- background: #f2f2f2;
- display: block;
- font-size: 14px;
- float: left;
- padding: 5px 10px;
- margin-right: 10px;
- border: 1px solid #e1e1e1;
- border-bottom: none;
-}
-
-#instance_tabs li.active a {
- background: #fff;
- padding-bottom: 8px;
- margin-bottom: -5px;
-}
-
-#main_content .nav-tabs {
- margin-bottom: 0;
-}
-
-#main_content .tab-content {
- border: 1px solid #ddd;
- border-top: 0 none;
- padding: 10px;
-}
-
-#main_content .workflow .modal-body {
- padding-left: 0;
- padding-right: 0;
-}
-
-#main_content .workflow .modal-body .tab-content {
- border-left: 0 none;
- border-right: 0 none;
- border-bottom: 0 none;
-}
-
-.tab_wrapper {
- padding-top: 50px;
-}
-
-/* Fix tooltip z-index to show above modals. Bootstrap bug 582*/
-.tooltip {
- z-index: 12000;
-}
-
-.volume_boot_disclosure {
- font-weight: bold;
- color: #555;
- cursor: pointer;
- background-image: url(/static/dashboard/img/right_droparrow.png);
- background-repeat: no-repeat;
- background-position: 130px center;
-}
-
-.volume_boot_disclosure.on {
- width: 334px;
- margin-bottom: 10px;
- border-bottom: solid 1px #E1E1E1;
- background-image: url(/static/dashboard/img/drop_arrow.png);
-}
-
-form div.clearfix.error {
- width: 308px;
-}
-
-.nav-tabs a {
- cursor: pointer;
-}
-
-.nav-tabs li.error a {
- color: #B94A48;
-}
-
-.nav-tabs li.error a:after {
- content: "*";
-}
-
-/* Region selector in header */
-
-#region_selector {
- position: absolute;
- z-index: 9999;
- right: 0;
- top: 24px;
-}
-
-#region_selector a { margin-left: 0; }
-
-#region_selector ul{
- float: left;
- margin-left: 5px;
- padding-right: 21px;
- width: 125px;
-}
-#region_selector ul:hover a { display: block; }
-
-#region_selector li a{
- padding: 3px 3px 3px 5px;
- display: none;
- background: #E1E1E1;
- margin-top: -10px;
-}
-
-#region_selector li:first-child p{
- background: #EDEDED url(/static/dashboard/img/drop_arrow.png) no-repeat 106px 9px !important;
- display: block;
- border: 1px solid #e1e1e1;
- padding: 5px;
-}
-
-iframe {
- border: none;
-}
-
-.item_detail ul li label {
- color: #000;
- font-weight: bold;
- display: block;
- margin-top: 5px;
-}
-
-.progress_bar {
- height: 100%;
- width: 100%;
- border: 1px solid #CCC;
- background-color: #CCC;
-}
-
-.progress_bar_fill,
-.progress_bar_selected {
- height: 100%;
- float: left;
-}
-
-.progress_bar_fill {
- background-color: #666;
-}
-
-.progress_bar_selected {
- background-color: #4790AE;
- width: 0;
-}
-
-.progress_bar_over {
- background-color: red;
-}
-
-.d3_quota_bar {
- width: 20%;
- margin-bottom: 8px;
- margin-top: 10px;
- float: left;
- text-align: center;
-}
-
-.quota-dynamic {
- overflow: hidden;
- margin-bottom: 8px;
-}
-
-.quota_title {
- color: #999;
- padding-bottom: 0;
- margin-bottom: 8px;
-}
-
-.quota_title strong {
- color: #000;
-}
-
-.quota_title strong span {
- font-weight: normal;
-}
-
-.quota_title p {
- float: right;
- margin-bottom: 0;
-}
-
-.quota_bar {
- height: 15px;
- margin: -8px 0 8px;
-}
-
-div .flavor_table {
- border: 1px solid #AAA;
- width: 100%;
- margin-bottom: 14px;
-}
-
-.flavor_table .flavor_name {
- white-space: nowrap;
- font-weight: bold;
- text-align: left;
- padding: 7px 12px 7px 7px;
- width: 160px;
-}
-
-#main_content .row-fluid {
- margin: 10px 0 20px;
-}
-
-#main_content .row-fluid:last-child {
- margin-bottom: 0;
-}
-
-.header_rule {
- margin: 0 0 10px;
-}
-
-.item_detail .detail_section {
- margin-bottom: 25px;
- float: left;
- margin-right: 50px;
-}
-
-.error .help-inline, .dynamic-error {
- background: #efdfdf;
- border: 1px solid #ead5d8;
- padding: 10px;
- display: block;
-}
-.dynamic-error {
- color: #b94a48;
- margin-bottom: 0.5em;
-}
-
-label.log-length {
- line-height: 28px;
- margin-right: 10px;
-}
-
-
-.progress-success.bar {
- background-color: #5eb95e;
- background-image: -moz-linear-gradient(top, #62c462, #57a957);
- background-image: -ms-linear-gradient(top, #62c462, #57a957);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));
- background-image: -webkit-linear-gradient(top, #62c462, #57a957);
- background-image: -o-linear-gradient(top, #62c462, #57a957);
- background-image: linear-gradient(top, #62c462, #57a957);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);
-}
-
-.progress_bar_fill.progress-warning.bar {
- background-color: #898989;
- background-image: -moz-linear-gradient(top, #999999, #333333);
- background-image: -ms-linear-gradient(top, #999999, #333333);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#999999), to(#333333));
- background-image: -webkit-linear-gradient(top, #999999, #333333);
- background-image: -o-linear-gradient(top, #999999, #333333);
- background-image: linear-gradient(top, #999999, #333333);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#999999', endColorstr='#333333', GradientType=0);
-}
-
-.progress_bar_over.bar {
- background-color: #dd514c;
- background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
- background-image: -ms-linear-gradient(top, #ee5f5b, #c43c35);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));
- background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
- background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
- background-image: linear-gradient(top, #ee5f5b, #c43c35);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);
-}
-
-.split_five div.control-group input[type="text"],
-.split_five div.control-group select {
- width: 120px;
-}
-
-.warning {
- background-color: @errorBackground;
- border-bottom: 1px solid @red;
- padding: 5px 10px;
- .warning-text {
- text-align: center;
- h3, a {
- display: inline-block;
- }
- h3 {
- vertical-align: bottom;
- }
- }
-}
-#admin_warning_detail {
- ul {
- list-style: circle;
- padding-left: 20px;
- margin-bottom: 10px;
- }
-}
-
-.no_split {
- margin-top: -60px;
-}
-
-/* Project Membership UI */
-.project_membership {
- min-height: 200px;
-
- /* Buttons */
- .btn-group {
- margin-left:0px;
- padding: 2px 10px 0 0;
- margin-bottom: 0px;
- border: 1px solid #DDD;
- border-bottom: none;
- }
- .btn-group .active {
- float: right;
- }
- a.btn-primary:hover {
- background-color: #04C;
- }
-
- /* Header */
- .help_text {
- margin-left: 15px;
- margin-bottom: 15px;
- }
- .users_title {
- color: #555;
- font-weight: bold;
- padding-left: 10px;
- float: left;
- }
- input {
- background: url(/static/dashboard/img/search.png) no-repeat 105px 5px whiteSmoke;
- }
- .fake_table_header {
- background-color: #F1F1F1;
- width: 306px;
- height: 38px;
- padding-top: 15px;
- border: 1px solid #DDD;
- border-bottom: none;
- }
-
- /* 'Fake table' body */
- .fake_table {
- margin-left: 5px;
- width: 315px;
- ul.no_results {
- width: 298px;
- }
- ul.btn-group:hover {
- background-color: #DDD;
- }
- }
- .left {
- .fake_table_header {
- width: 318px;
- }
- }
- .right {
- .fake_table_header {
- width: 318px;
- margin-left: -15px;
- }
- .fake_table ul.no_results {
- margin-left: -20px;
- }
- }
-
- /* User lists */
- .member {
- padding: 10px;
- text-align: left;
- }
- .project_members {
- margin-left: -20px;
- }
- .project_members ul.btn-group,
- .available_users ul.btn-group {
- width: 308px;
- }
- .dark_stripe {
- background-color: #F9F9F9;
- }
- .light_stripe {
- background-color: white;
- }
- .last_stripe {
- border-bottom: 1px solid #DDD;
- }
-
- /* List filtering */
- .filter {
- width: 120px;
- margin: -5px 13px 15px 0px;
- float: right;
- }
- .no_results {
- border: 1px solid #DDD;
- padding: 10px;
- opacity: 0.5;
- }
-
- /* Role dropdown menus */
- .role_dropdown li {
- cursor: pointer;
- background: none;
- float: none;
- display: block;
- padding: 5px 10px;
- color: black;
- text-align: left;
- border-radius: 0;
- border: 0 none;
- -webkit-box-shadow: none;
- -moz-box-shadow: none;
- box-shadow: none;
- z-index: 99999;
- i {
- opacity: 0;
- }
-
- &:hover {
- background-color: #CDCDCD;
- }
- &.selected i {
- opacity: 1;
- }
- }
- .dropdown-menu.role_dropdown {
- right: 0;
- left: auto;
- }
- .nav .role_options {
- float: right;
- padding-right: 5px;
- }
-}
-
-/* Inline user creation */
-.add_user_btn {
- display: inline;
-}
-#add_user {
- clear: both;
-}
-.add_user {
- float: right;
- margin-top: 10px;
- margin-right: 15px;
-}
-
-/* Fixes overflow on dropdowns in modal */
-.dropdown_fix {
- overflow: visible;
-}
-
-/* Replaces CPU hungry spin.js with animated gif */
-.loading_gif {
- width: 35px;
- height: 13px;
- padding-top: 2px;
- padding-right: 5px;
- float: left;
-}
-
-.action_required_img {
- width: 35px;
- height: 13px;
- padding-top: 2px;
- padding-right: 5px;
- float: left;
-}
-
-//ResourceBrowser
-@dataTableBorderWidth: 1px;
-@dataTableBorderColor: #DDD;
-
-@actionsColumnPadding: 10px;
-
-@smallButtonHeight: 28px;
-@tdHeight: @smallButtonHeight;
-
-@tableCellPadding: 8px;
-
-@contentTableWidth: 70%;
-@navigationTableWidth: 30%;
-@browserWrapperWidth: 100%;
-
-/* ResourceBrowser style */
-#browser_wrapper {
- width: @browserWrapperWidth;
- min-width: 1000px;
- background-color: @grayLighter;
- border: @dataTableBorderWidth solid @dataTableBorderColor;
- .border-radius(4px);
- .tfoot {
- clear: both;
- padding: 8px;
- border-top: 1px solid @dataTableBorderColor;
- background-color: #F1F1F1;
- font-size: 11px;
- line-height: 14px;
- span {
- display: inline-block;
- &.navigation_table_count {
- width: @navigationTableWidth;
- }
- }
- }
- form, table{
- margin-bottom: 0;
- }
- .navigation_wrapper, .content_wrapper{
- position: relative;
- float: left;
- }
- div.navigation_wrapper {
- z-index: 10;
- width: @navigationTableWidth;
- div.table_wrapper,
- thead th.table_header {
- border-right: 0 none;
- border-top-right-radius: 0;
- }
- td {
- &:first-child {
- border-left: 0 none;
- }
- &.breadcrumb_td {
- padding-right: 0px;
- max-width: 200px;
- }
- }
- tr.current_selected td {
- background-color: #E9F5FA;
- }
- tfoot td {
- border-right: 0 none;
- border-bottom-right-radius: 0;
- }
- ul.breadcrumb {
- padding-right: 0px;
- border-top-right-radius: 0px;
- border-bottom-right-radius: 0px;
- border-right: none;
- white-space: nowrap;
- }
- tbody td {
- border-right: @dataTableBorderWidth solid @dataTableBorderColor;
- background-color: @white;
- }
- }
- div.content_wrapper {
- width: @contentTableWidth;
- div.table_wrapper,
- thead th.table_header {
- border-left: 0 none;
- border-top-left-radius: 0;
- }
- td{
- border-bottom: @dataTableBorderWidth solid @dataTableBorderColor;
- &:last-child {
- border-right: 0 none;
- }
- &.breadcrumb_td {
- padding-left: 0px;
- }
- }
- tfoot td {
- border-left: 0 none;
- border-bottom-left-radius: 0;
- }
- /* FIXME(Ke Wu): for now there are two breadcrumb tr in both table
- * and this one in the content table is hidden. This hack is made to
- * fix the alignment of two table, needs a better solution in the
- * future.
- */
- ul.breadcrumb {
- padding-left: 0px;
- border-top-left-radius: 0px;
- border-bottom-left-radius: 0px;
- border-left: none;
- li {
- visibility: hidden;
- }
- }
- }
- table {
- border-collapse: collapse;
- thead {
- tr th {
- border-bottom: none;
- background-color: @grayLighter;
- }
- }
- tbody {
- tr:last-child td {
- border-bottom: 1px solid #ddd;
- border-radius: 0;
- }
- tr.empty td {
- height: @tdHeight;
- padding: @actionsColumnPadding;
- }
- td.actions_column {
- position: static;
- }
- }
- }
- .breadcrumb{
- padding: 6px;
- margin: 0 0 1px 0;
- }
-}
-
-/* Styling for inline object creation buttons */
-.btn-inline {
- margin-bottom: 9px;
-}
-.modal-body fieldset .form-field select[data-add-item-url] {
- width: 275px;
- margin-right: 2px;
-}
-
-/* Styling for draged network object */
-#networkListSortContainer {
- display: none;
-}
-.networklist {
- padding: 6px;
- background: #eee;
- border: 1px solid #ccc;
- min-height: 2em;
- width: auto !important;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- li {
- width: 226px;
- list-style-type: none;
- margin: 6px auto;
- padding: 3px;
- background: #fff;
- border: 1px solid #aaa;
- line-height: 18px;
- border-radius: 3px;
- cursor: move;
- padding-left: 23px;
- background: white url(/static/dashboard/img/drag.png) no-repeat 11px 50%;
- em {
- font-size: 0.5em;
- line-height: 1em;
- color:#999;
- font-style: normal;
- margin-left: 0.8em;
- }
- i {
- margin-right: 5px;
- vertical-align: middle;
- }
- a.btn {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- font-size: 11px;
- line-height: 12px;
- padding: 2px 5px 3px;
- margin-right: 1px;
- width: 18px;
- text-align: center;
- //position: absolute;
- right:5px;
- vertical-align: middle;
- float: right;
- &:before {
- content: "+";
- }
- }
- }
- li.ui-sortable-helper {
- background-color: #def;
- }
- li.ui-state-highlight {
- border: 1px dotted #ccc;
- background: #efefef;
- height: 0.5em;
- }
- li:after {
- visibility: hidden;
- display: block;
- font-size: 0;
- content: " ";
- clear: both;
- height: 0;
- }
-}
-#selected_network {
- margin-bottom: 1.5em;
- counter-reset:v1 0;
- background: #edf9ff;
- border:1px solid #c0d9e4;
- li {
- position: relative;
- a.btn {
- &:before {
- content: "-";
- }
- }
- }
- li:before {
- content:"nic:"counter(v1);
- counter-increment:v1;
- display: inline-block;
- margin-right: 5px;
- background: #666;
- color:#fff;
- font-size: 90%;
- padding: 0px 4px;
- vertical-align: middle;
- border-radius: 2px;
- position: absolute;
- left: -2em;
- }
- &.dragging {
- li:before {
- content:"nic:";
- background-color:rgba(102,102,102,0.5);
- padding-right: 10px;
- }
- li.ui-state-highlight:before {
- content:"";
- background:transparent;
- }
- }
-
-}
-
-/* Styling for network topology */
-.box-sizing(@box: border-box) {
- -webkit-box-sizing: @box;
- -moz-box-sizing: @box;
- -ms-box-sizing: @box;
- -o-box-sizing: @box;
- box-sizing: @box;
-}
-
-@-webkit-keyframes progress-bar-stripes {
- from {
- background-position: 20px 0;
- }
- to {
- background-position: 0 0;
- }
-}
-
-@-moz-keyframes progress-bar-stripes {
- from {
- background-position: 20px 0;
- }
- to {
- background-position: 0 0;
- }
-}
-
-@-ms-keyframes progress-bar-stripes {
- from {
- background-position: 20px 0;
- }
- to {
- background-position: 0 0;
- }
-}
-
-@-o-keyframes progress-bar-stripes {
- from {
- background-position: 0 0;
- }
- to {
- background-position: 20px 0;
- }
-}
-
-@keyframes progress-bar-stripes {
- from {
- background-position: 20px 0;
- }
- to {
- background-position: 0 0;
- }
-}
-
-#topologyCanvas {
- .box-sizing();
- width: 100%;
- height: 500px;
- padding: 25px;
- padding-left: 50px;
- background: #efefef;
- div.nodata {
- font-size: 150%;
- font-weight: bold;
- text-align: center;
- padding-top: 200px;
- display: none;
- }
-}
-div.networks {
- height: 100%;
-}
-div.network {
- .box-sizing();
- float: left;
- width: 270px;
- height: 100%;
- position: relative;
- .nicname {
- .box-sizing();
- height: 100%;
- width: 17px;
- border-radius: 17px;
- z-index: 200;
- color:#fff;
- position: absolute;
- left: -8px;
- top: 0px;
- cursor: pointer;
- &:hover {
- background-image: -webkit-linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15));
- background-image: -moz-linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15));
- background-image: -ms-linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15));
- background-image: -o-linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15));
- background-image: linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15));
- background-size: 10px 10px;
- }
- &.nourl {
- cursor: auto;
- &:hover {
- background-image:none;
- }
- }
- h3 {
- font-size: 12px;
- line-height: 1;
- position: relative;
- font-weight: normal;
- top:55%;
- color:#fff;
- left:-1px;
- letter-spacing: 0.2em;
- -webkit-transform: rotate(-90deg);
- -moz-transform: rotate(-90deg);
- -ms-transform: rotate(-90deg);
- -o-transform: rotate(-90deg);
- transform: rotate(-90deg);
-
- white-space: nowrap;
- text-shadow: 0px 0px 5px #000;
- }
- span.ip {
- position: absolute;
- bottom:-10px;
- left:20px;
- color: #000;
- display: block;
- font-weight: normal;
- font-size: 90%;
- letter-spacing: 0.2em;
- -webkit-transform: rotate(-90deg);
- -moz-transform: rotate(-90deg);
- -ms-transform: rotate(-90deg);
- -o-transform: rotate(-90deg);
- transform: rotate(-90deg);
- -webkit-transform-origin: 0% 0%;
- -moz-transform-origin: 0% 0%;
- -ms-transform-origin: 0% 0%;
- -o-transform-origin: 0% 0%;
- transform-origin: 0% 0%;
- white-space: nowrap;
- text-shadow: 0px 0px 2px #fff,0px 0px 2px #fff;
- }
- }
- .router, .server, .device {
- .box-sizing();
- cursor: pointer;
- width: 90px;
- border: 3px solid #444;
- position: absolute;
- top:30px;
- left:90px;
- color:#fff;
- padding: 0 3px;
- background: #666;
- margin-bottom: 20px;
- border-radius: 8px;
- &:before {
- content: "";
- width: 20px;
- height: 20px;
- border: 2px solid #444;
- line-height: 1.2;
- position: absolute;
- border-radius: 20px;
- top:-10px;
- left:-10px;
- background:#fff url(/static/dashboard/img/router.png) no-repeat center center;
- background-size: 16px 16px;
- }
- &:after {
- content: "";
- width: 100%;
- line-height: 1.2;
- position: absolute;
- text-align: center;
- border-radius: 0;
- background: #444;
- color: #fff;
- font-size: 11px;
- height: 1.5em;
- bottom:0px;
- left: 0px;
- }
- span.devicename {
- position: absolute;
- color: #fff;
- bottom: 0px;
- font-size: 12px;
- line-height: 14px;
- width: 100%;
- text-align: center;
- z-index:300;
- left:-2px;
- }
- span.name {
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- display: block;
- font-size : 12px;
- position: relative;
- z-index:10;
- text-align: center;
- top:4px;
- padding: 0 3px;
- }
- div.port {
- text-align: right;
- min-width: 90px;
- height: 10px;
- font:0px/0px sans-serif;
- position: absolute;
- left:-91px;
- top:8px;
- background-color: #37a9e3;
- background-image: none;
- -webkit-background-size: 20px 20px;
- -moz-background-size: 20px 20px;
- -o-background-size: 20px 20px;
- background-size: 20px 20px;
- z-index:100;
- span.ip {
- .box-sizing();
- color: #333;
- font-size: 9px;
- line-height: 1;
- text-shadow: 0px -1px #fff;
- position: relative;
- width: 90px;
- display: inline-block;
- padding-right:8px;
- padding-left: 8px;
- word-wrap:break-word;
- word-break:break-all;
- }
- &.right {
- left:auto;
- right:-92px;
- width: 92px;
- text-align: left;
- span.ip {
- }
- }
- }
- &:hover {
- div.port {
- cursor:pointer;
- background-color: #2688c0;
- -webkit-animation: progress-bar-stripes 1s linear infinite;
- -moz-animation: progress-bar-stripes 1s linear infinite;
- -ms-animation: progress-bar-stripes 1s linear infinite;
- -o-animation: progress-bar-stripes 1s linear infinite;
- animation: progress-bar-stripes 1s linear infinite;
- &:hover {
- -webkit-animation: progress-bar-stripes 0.3s linear infinite;
- -moz-animation: progress-bar-stripes 0.3s linear infinite;
- -ms-animation: progress-bar-stripes 0.3s linear infinite;
- -o-animation: progress-bar-stripes 0.3s linear infinite;
- animation: progress-bar-stripes 0.3s linear infinite;
- }
- &.nourl {
- cursor: auto;
- background-image:none;
- &:hover {
- background-image:none;
- }
- }
- }
- border-color: #222;
- &:after {
- background-color: #222;
- border-color: #222;
- }
- }
- }
- .device {
- border:none;
- background: transparent;
- }
- .server {
- &:before {
- background:#fff url(/static/dashboard/img/server.png) no-repeat center center;
- background-size: 14px 14px;
- }
- background: #fff;
- color:#333;
- }
-}
-
-.launchButtons {
- text-align: right;
- margin: 10px 0px 15px 10px;
- a.btn {
- margin-left: 10px;
- }
-}
-
-/**** Resource Topology CSS ****/
-.link {stroke: #000;stroke-width: 1.5px;}
-.node {cursor:pointer;}
-.node text {font: 12px sans-serif;}
-
-#resource_container {position:relative;}
-#stack_box {position:absolute;width:300px;top:10px;left:10px;}
-#stack_box h3 {font-size:11pt;line-height:20px;}
-#stack_box p {margin:0;font-size:9pt;line-height:14px;}
-#stack_box a {margin:0;font-size:9pt;line-height:14px;}
-#stack_box img {float:left;}
-#stack_box #stack_info {float:left;white-space:normal;width:200px;}
-
-#info_box {position:absolute;width:300px;top:100px;left:10px;}
-#info_box h3 {font-size:9pt;line-height:20px;}
-#info_box p {margin:0;font-size:9pt;line-height:14px;}
-#info_box a {margin:0;font-size:9pt;line-height:14px;}
-#info_box .error {color:darkred;} \ No newline at end of file
diff --git a/openstack_dashboard/templates/403.html b/openstack_dashboard/templates/403.html
deleted file mode 100644
index 0e36553e..00000000
--- a/openstack_dashboard/templates/403.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{% extends "base.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block title %} - {% trans "Forbidden" %}{% endblock %}
-
-{% block content %}
- <div id="right_content">
- <div id="page_head">
- <h2 id="page_heading">{% trans "Forbidden" %}</h2>
- <p id="page_description">{% trans "You do not have the required privileges to access this content.
- If you believe this message to be in error, please contact your project manager." %}</p>
- </div>
- </div>
-{% endblock %}
-
-{% block sidebar %}
- <div id="sidebar">
- <ul id="navigation">
- {% block nav_home %}
- <li><h3><a href="{% url 'index' %}">{% trans "Home" %}</a></h3></li>
- {% endblock %}
-
- {% block nav_projects %}
- <li><h3><a href="{% url 'index' %}">{% trans "Projects" %}</a></h3></li>
- {% endblock %}
- </ul>
- </div> <!-- end sidebar -->
-{% endblock %}
diff --git a/openstack_dashboard/templates/404.html b/openstack_dashboard/templates/404.html
deleted file mode 100644
index 12a05225..00000000
--- a/openstack_dashboard/templates/404.html
+++ /dev/null
@@ -1,28 +0,0 @@
-{% extends "base.html" %}
-{% load i18n %}
-{% load url from future %}
-
-{% block title %} - {% trans "Page Not Found" %}{% endblock %}
-
-{% block content %}
- <div id="right_content">
- <div id="page_head">
- <h2 id="page_heading">{% trans "The page you were looking for doesn't exist" %}</h2>
- <p id="page_description">{% trans "You may have mistyped the address or the page may have moved." %}</p>
- </div>
- </div>
-{% endblock %}
-
-{% block sidebar %}
- <div id="sidebar">
- <ul id="navigation">
- {% block nav_home %}
- <li><h3><a href="{% url 'index' %}">{% trans "Home" %}</a></h3></li>
- {% endblock %}
-
- {% block nav_projects %}
- <li><h3><a href="{% url 'index' %}">{% trans "Projects" %}</a></h3></li>
- {% endblock %}
- </ul>
- </div> <!-- end sidebar -->
-{% endblock %}
diff --git a/openstack_dashboard/templates/500.html b/openstack_dashboard/templates/500.html
deleted file mode 100644
index fb51211c..00000000
--- a/openstack_dashboard/templates/500.html
+++ /dev/null
@@ -1,82 +0,0 @@
-{% load branding i18n staticfiles %}
-{% load load_config from horizon %}
-
-{% load_config as HORIZON_CONFIG %}
-
-
-{% comment %}
-
- NB: The context for 500 pages is an empty dict.
- Don't add any content here that depends on things from
- the context.
-
-{% endcomment %}
-
-<!DOCTYPE html>
-<html>
- <head>
- <meta content='text/html; charset=utf-8' http-equiv='Content-Type' />
- <link rel="shortcut icon" href="{% static "dashboard/img/favicon.ico" %}"/>
- <title>{% trans "Server error" %} - {% site_branding %}</title>
- {% block css %}
- <style>
- a {
- color: #43a1d6;
- text-decoration: none;
- }
- body {
- color: rgb(106, 106, 106);
- text-align: center;
- font-weight: normal;
- background: none repeat scroll 0% 0% rgb(250, 250, 250);
- }
- div#container {
- position: absolute;
- top: 80px;
- padding-top: 170px;
- margin: 0px 0px 0px -196px;
- left: 50%;
- width: 390px;
-
- background: url("{% static "dashboard/img/logo.png" %}") no-repeat scroll center 35px padding-box rgb(255, 255, 255);
- border: 1px solid rgb(225, 225, 225);
-
- -webkit-border-radius: 6px;
- -moz-border-radius: 6px;
- border-radius: 6px;
-
- box-shadow: 0px 3px 7px rgba(0, 0, 0, 0.3);
- -webkit-box-shadow: 0px 3px 7px rgba(0, 0, 0, 0.3);
- -moz-box-shadow: 0px 3px 7px rgba(0, 0, 0, 0.3);
- }
- h2 {
- font-weight: normal;
- }
- div#container > div {
- padding: 25px;
- }
- </style>
- {% endblock %}
- </head>
- <body id="{% block body_id %}{% endblock %}">
- {% block page_header %}{% endblock %}
- {% block content %}
- <div id="container">
- <div id="text">
- {% block text %}
- <h2>{% trans "Something went wrong!" %}</h2>
- <p>{% trans "An unexpected error has occurred. Try refreshing the page. If that doesn't help, contact your local administrator." %}</p>
- {% endblock %}
- </div>
- <div id="links">
- {% block links %}
- <p><a href="/">{% trans "Home" %}</a></p>
- <p><a href="{{ HORIZON_CONFIG.help_url }}">{% trans "Help" %}</a></p>
- {% endblock %}
- </div>
- </div>
- {% endblock %}
- {% block footer %}{% endblock %}
- {% block js %}{% endblock %}
- </body>
-</html>
diff --git a/openstack_dashboard/templates/_header.html b/openstack_dashboard/templates/_header.html
deleted file mode 100644
index a18b6ed0..00000000
--- a/openstack_dashboard/templates/_header.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% load i18n %}
-{% load url from future %}
-<div id="user_info" class="pull-right">
- <span>{% trans "Logged in as" %}: {{ request.user.username }}</span>
- <a href="{% url 'horizon:settings:user:index' %}">{% trans "Settings" %}</a>
- {% if HORIZON_CONFIG.help_url %}
- <a href="{{ HORIZON_CONFIG.help_url }}" target="_new">{% trans "Help" %}</a>
- {% endif %}
- <a href="{% url 'logout' %}">{% trans "Sign Out" %}</a>
- {% include "horizon/common/_region_selector.html" %}
-</div>
diff --git a/openstack_dashboard/templates/_stylesheets.html b/openstack_dashboard/templates/_stylesheets.html
deleted file mode 100644
index 66c40a6f..00000000
--- a/openstack_dashboard/templates/_stylesheets.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{% load compress %}
-
-{% compress css %}
-<link href='{{ STATIC_URL }}dashboard/less/horizon.less' type='text/less' media='screen' rel='stylesheet' />
-{% endcompress %}
-
-<link rel="shortcut icon" href="{{ STATIC_URL }}dashboard/img/favicon.ico"/>
diff --git a/openstack_dashboard/test/__init__.py b/openstack_dashboard/test/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/test/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/test/api_tests/__init__.py b/openstack_dashboard/test/api_tests/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/test/api_tests/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/test/api_tests/base_tests.py b/openstack_dashboard/test/api_tests/base_tests.py
deleted file mode 100644
index d488757c..00000000
--- a/openstack_dashboard/test/api_tests/base_tests.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from __future__ import absolute_import
-
-from horizon import exceptions
-
-from openstack_dashboard.api import base as api_base
-from openstack_dashboard.test import helpers as test
-
-
-class APIResource(api_base.APIResourceWrapper):
- """ Simple APIResource for testing """
- _attrs = ['foo', 'bar', 'baz']
-
- @staticmethod
- def get_instance(innerObject=None):
- if innerObject is None:
-
- class InnerAPIResource(object):
- pass
-
- innerObject = InnerAPIResource()
- innerObject.foo = 'foo'
- innerObject.bar = 'bar'
- return APIResource(innerObject)
-
-
-class APIDict(api_base.APIDictWrapper):
- """ Simple APIDict for testing """
- _attrs = ['foo', 'bar', 'baz']
-
- @staticmethod
- def get_instance(innerDict=None):
- if innerDict is None:
- innerDict = {'foo': 'foo',
- 'bar': 'bar'}
- return APIDict(innerDict)
-
-
-# Wrapper classes that only define _attrs don't need extra testing.
-class APIResourceWrapperTests(test.TestCase):
- def test_get_attribute(self):
- resource = APIResource.get_instance()
- self.assertEqual(resource.foo, 'foo')
-
- def test_get_invalid_attribute(self):
- resource = APIResource.get_instance()
- self.assertNotIn('missing', resource._attrs,
- msg="Test assumption broken. Find new missing attribute")
- with self.assertRaises(AttributeError):
- resource.missing
-
- def test_get_inner_missing_attribute(self):
- resource = APIResource.get_instance()
- with self.assertRaises(AttributeError):
- resource.baz
-
- def test_repr(self):
- resource = APIResource.get_instance()
- resource_str = resource.__repr__()
- self.assertIn('foo', resource_str)
- self.assertIn('bar', resource_str)
- self.assertNotIn('baz', resource_str)
-
-
-class APIDictWrapperTests(test.TestCase):
- # APIDict allows for both attribute access and dictionary style [element]
- # style access. Test both
- def test_get_item(self):
- resource = APIDict.get_instance()
- self.assertEqual(resource.foo, 'foo')
- self.assertEqual(resource['foo'], 'foo')
-
- def test_get_invalid_item(self):
- resource = APIDict.get_instance()
- self.assertNotIn('missing', resource._attrs,
- msg="Test assumption broken. Find new missing attribute")
- with self.assertRaises(AttributeError):
- resource.missing
- with self.assertRaises(KeyError):
- resource['missing']
-
- def test_get_inner_missing_attribute(self):
- resource = APIDict.get_instance()
- with self.assertRaises(AttributeError):
- resource.baz
- with self.assertRaises(KeyError):
- resource['baz']
-
- def test_get_with_default(self):
- resource = APIDict.get_instance()
-
- self.assertEqual(resource.get('foo'), 'foo')
-
- self.assertIsNone(resource.get('baz'))
-
- self.assertEqual('retValue', resource.get('baz', 'retValue'))
-
-
-class ApiHelperTests(test.TestCase):
- """ Tests for functions that don't use one of the api objects """
-
- def test_url_for(self):
- url = api_base.url_for(self.request, 'image')
- self.assertEqual(url, 'http://public.glance.example.com:9292/v1')
-
- url = api_base.url_for(self.request, 'image', endpoint_type='adminURL')
- self.assertEqual(url, 'http://admin.glance.example.com:9292/v1')
-
- url = api_base.url_for(self.request, 'compute')
- self.assertEqual(url, 'http://public.nova.example.com:8774/v2')
-
- url = api_base.url_for(self.request, 'compute',
- endpoint_type='adminURL')
- self.assertEqual(url, 'http://admin.nova.example.com:8774/v2')
-
- url = api_base.url_for(self.request, 'volume')
- self.assertEqual(url, 'http://public.nova.example.com:8776/v1')
-
- url = api_base.url_for(self.request, 'volume',
- endpoint_type="internalURL")
- self.assertEqual(url, 'http://int.nova.example.com:8776/v1')
-
- url = api_base.url_for(self.request, 'volume',
- endpoint_type='adminURL')
- self.assertEqual(url, 'http://admin.nova.example.com:8776/v1')
-
- self.assertNotIn('notAnApi', self.request.user.service_catalog,
- 'Select a new nonexistent service catalog key')
- with self.assertRaises(exceptions.ServiceCatalogException):
- url = api_base.url_for(self.request, 'notAnApi')
-
- self.request.user.services_region = "RegionTwo"
- url = api_base.url_for(self.request, 'compute')
- self.assertEqual(url, 'http://public.nova2.example.com:8774/v2')
-
- self.request.user.services_region = "RegionTwo"
- url = api_base.url_for(self.request, 'compute',
- endpoint_type='adminURL')
- self.assertEqual(url, 'http://admin.nova2.example.com:8774/v2')
-
- self.request.user.services_region = "RegionTwo"
- with self.assertRaises(exceptions.ServiceCatalogException):
- url = api_base.url_for(self.request, 'image')
-
- self.request.user.services_region = "bogus_value"
- url = api_base.url_for(self.request, 'identity',
- endpoint_type='adminURL')
- self.assertEqual(url, 'http://admin.keystone.example.com:35357/v2.0')
-
- self.request.user.services_region = "bogus_value"
- with self.assertRaises(exceptions.ServiceCatalogException):
- url = api_base.url_for(self.request, 'image')
diff --git a/openstack_dashboard/test/api_tests/cinder_tests.py b/openstack_dashboard/test/api_tests/cinder_tests.py
deleted file mode 100644
index d395a54f..00000000
--- a/openstack_dashboard/test/api_tests/cinder_tests.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class CinderApiTests(test.APITestCase):
- def test_volume_list(self):
- search_opts = {'all_tenants': 1}
- volumes = self.volumes.list()
- cinderclient = self.stub_cinderclient()
- cinderclient.volumes = self.mox.CreateMockAnything()
- cinderclient.volumes.list(search_opts=search_opts,).AndReturn(volumes)
- self.mox.ReplayAll()
-
- # No assertions are necessary. Verification is handled by mox.
- api.cinder.volume_list(self.request, search_opts=search_opts)
-
- def test_volume_snapshot_list(self):
- volume_snapshots = self.volume_snapshots.list()
- cinderclient = self.stub_cinderclient()
- cinderclient.volume_snapshots = self.mox.CreateMockAnything()
- cinderclient.volume_snapshots.list().AndReturn(volume_snapshots)
- self.mox.ReplayAll()
-
- api.cinder.volume_snapshot_list(self.request)
-
- def test_volume_snapshot_list_no_volume_configured(self):
- # remove volume from service catalog
- catalog = self.service_catalog
- for service in catalog:
- if service["type"] == "volume":
- self.service_catalog.remove(service)
- volume_snapshots = self.volume_snapshots.list()
-
- cinderclient = self.stub_cinderclient()
- cinderclient.volume_snapshots = self.mox.CreateMockAnything()
- cinderclient.volume_snapshots.list().AndReturn(volume_snapshots)
- self.mox.ReplayAll()
-
- api.cinder.volume_snapshot_list(self.request)
diff --git a/openstack_dashboard/test/api_tests/glance_tests.py b/openstack_dashboard/test/api_tests/glance_tests.py
deleted file mode 100644
index 1ba52303..00000000
--- a/openstack_dashboard/test/api_tests/glance_tests.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django.conf import settings
-from django.test.utils import override_settings
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class GlanceApiTests(test.APITestCase):
- @override_settings(API_RESULT_PAGE_SIZE=2)
- def test_image_list_detailed_no_pagination(self):
- # Verify that all images are returned even with a small page size
- api_images = self.images.list()
- filters = {}
- limit = getattr(settings, 'API_RESULT_LIMIT', 1000)
-
- glanceclient = self.stub_glanceclient()
- glanceclient.images = self.mox.CreateMockAnything()
- glanceclient.images.list(page_size=limit,
- limit=limit,
- filters=filters,).AndReturn(iter(api_images))
- self.mox.ReplayAll()
-
- images, has_more = api.glance.image_list_detailed(self.request)
- self.assertItemsEqual(images, api_images)
- self.assertFalse(has_more)
-
- @override_settings(API_RESULT_PAGE_SIZE=2)
- def test_image_list_detailed_pagination(self):
- # The total snapshot count is over page size, should return
- # page_size images.
- filters = {}
- page_size = settings.API_RESULT_PAGE_SIZE
- limit = getattr(settings, 'API_RESULT_LIMIT', 1000)
-
- api_images = self.images.list()
- images_iter = iter(api_images)
-
- glanceclient = self.stub_glanceclient()
- glanceclient.images = self.mox.CreateMockAnything()
- # Pass back all images, ignoring filters
- glanceclient.images.list(limit=limit,
- page_size=page_size + 1,
- filters=filters,).AndReturn(images_iter)
- self.mox.ReplayAll()
-
- images, has_more = api.glance.image_list_detailed(self.request,
- marker=None,
- filters=filters,
- paginate=True)
- expected_images = api_images[:page_size]
- self.assertItemsEqual(images, expected_images)
- self.assertTrue(has_more)
- # Ensure that only the needed number of images are consumed
- # from the iterator (page_size + 1).
- self.assertEqual(len(list(images_iter)),
- len(api_images) - len(expected_images) - 1)
-
- @override_settings(API_RESULT_PAGE_SIZE=2)
- def test_image_list_detailed_pagination_marker(self):
- # Tests getting a second page with a marker.
- filters = {}
- page_size = settings.API_RESULT_PAGE_SIZE
- limit = getattr(settings, 'API_RESULT_LIMIT', 1000)
- marker = 'nonsense'
-
- api_images = self.images.list()[page_size:]
- images_iter = iter(api_images)
-
- glanceclient = self.stub_glanceclient()
- glanceclient.images = self.mox.CreateMockAnything()
- # Pass back all images, ignoring filters
- glanceclient.images.list(limit=limit,
- page_size=page_size + 1,
- filters=filters,
- marker=marker).AndReturn(images_iter)
- self.mox.ReplayAll()
-
- images, has_more = api.glance.image_list_detailed(self.request,
- marker=marker,
- filters=filters,
- paginate=True)
- expected_images = api_images[:page_size]
- self.assertItemsEqual(images, expected_images)
- self.assertTrue(has_more)
- self.assertEqual(len(list(images_iter)),
- len(api_images) - len(expected_images) - 1)
diff --git a/openstack_dashboard/test/api_tests/heat_tests.py b/openstack_dashboard/test/api_tests/heat_tests.py
deleted file mode 100644
index 95ff3b76..00000000
--- a/openstack_dashboard/test/api_tests/heat_tests.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class HeatApiTests(test.APITestCase):
- def test_stack_list(self):
- api_stacks = self.stacks.list()
-
- heatclient = self.stub_heatclient()
- heatclient.stacks = self.mox.CreateMockAnything()
- heatclient.stacks.list().AndReturn(iter(api_stacks))
- self.mox.ReplayAll()
-
- stacks = api.heat.stacks_list(self.request)
- self.assertItemsEqual(stacks, api_stacks)
diff --git a/openstack_dashboard/test/api_tests/keystone_tests.py b/openstack_dashboard/test/api_tests/keystone_tests.py
deleted file mode 100644
index 02223d45..00000000
--- a/openstack_dashboard/test/api_tests/keystone_tests.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from __future__ import absolute_import
-
-from keystoneclient.v2_0 import client as keystone_client
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class FakeConnection(object):
- pass
-
-
-class ClientConnectionTests(test.TestCase):
- def setUp(self):
- super(ClientConnectionTests, self).setUp()
- self.mox.StubOutWithMock(keystone_client, "Client")
- self.internal_url = api.base.url_for(self.request,
- 'identity',
- endpoint_type='internalURL')
- self.admin_url = api.base.url_for(self.request,
- 'identity',
- endpoint_type='adminURL')
- self.conn = FakeConnection()
-
-
-class RoleAPITests(test.APITestCase):
- def setUp(self):
- super(RoleAPITests, self).setUp()
- self.role = self.roles.member
- self.roles = self.roles.list()
-
- def test_remove_tenant_user(self):
- """
- Tests api.keystone.remove_tenant_user
-
- Verifies that remove_tenant_user is called with the right arguments
- after iterating the user's roles.
-
- There are no assertions in this test because the checking is handled
- by mox in the VerifyAll() call in tearDown().
- """
- keystoneclient = self.stub_keystoneclient()
- tenant = self.tenants.first()
-
- keystoneclient.roles = self.mox.CreateMockAnything()
- keystoneclient.roles.roles_for_user(self.user.id,
- tenant.id).AndReturn(self.roles)
- for role in self.roles:
- keystoneclient.roles.revoke(role.id,
- domain=None,
- group=None,
- project=tenant.id,
- user=self.user.id)
- self.mox.ReplayAll()
- api.keystone.remove_tenant_user(self.request, tenant.id, self.user.id)
-
- def test_get_default_role(self):
- keystoneclient = self.stub_keystoneclient()
- keystoneclient.roles = self.mox.CreateMockAnything()
- keystoneclient.roles.list().AndReturn(self.roles)
- self.mox.ReplayAll()
- role = api.keystone.get_default_role(self.request)
- self.assertEqual(role, self.role)
- # Verify that a second call doesn't hit the API again,
- # (it would show up in mox as an unexpected method call)
- role = api.keystone.get_default_role(self.request)
-
-
-class ServiceAPITests(test.APITestCase):
- def test_service_wrapper(self):
- catalog = self.service_catalog
- identity_data = api.base.get_service_from_catalog(catalog, "identity")
- identity_data['id'] = 1
- region = identity_data["endpoints"][0]["region"]
- service = api.keystone.Service(identity_data, region)
- self.assertEqual(unicode(service), u"identity (native backend)")
- self.assertEqual(service.region,
- identity_data["endpoints"][0]["region"])
- self.assertEqual(service.url,
- "http://int.keystone.example.com:5000/v2.0")
- self.assertEqual(service.public_url,
- "http://public.keystone.example.com:5000/v2.0")
- self.assertEqual(service.host, "int.keystone.example.com")
-
- def test_service_wrapper_service_in_region(self):
- catalog = self.service_catalog
- compute_data = api.base.get_service_from_catalog(catalog, "compute")
- compute_data['id'] = 1
- region = compute_data["endpoints"][1]["region"]
- service = api.keystone.Service(compute_data, region)
- self.assertEqual(unicode(service), u"compute")
- self.assertEqual(service.region,
- compute_data["endpoints"][1]["region"])
- self.assertEqual(service.url,
- "http://int.nova2.example.com:8774/v2")
- self.assertEqual(service.public_url,
- "http://public.nova2.example.com:8774/v2")
- self.assertEqual(service.host, "int.nova2.example.com")
diff --git a/openstack_dashboard/test/api_tests/lbaas_tests.py b/openstack_dashboard/test/api_tests/lbaas_tests.py
deleted file mode 100644
index 28773213..00000000
--- a/openstack_dashboard/test/api_tests/lbaas_tests.py
+++ /dev/null
@@ -1,339 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013, Big Switch Networks, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-from neutronclient.v2_0.client import Client as neutronclient
-
-
-class LbaasApiTests(test.APITestCase):
- @test.create_stubs({neutronclient: ('create_vip',)})
- def test_vip_create(self):
- vip1 = self.api_vips.first()
- form_data = {'address': vip1['address'],
- 'name': vip1['name'],
- 'description': vip1['description'],
- 'subnet_id': vip1['subnet_id'],
- 'protocol_port': vip1['protocol_port'],
- 'protocol': vip1['protocol'],
- 'pool_id': vip1['pool_id'],
- 'session_persistence': vip1['session_persistence'],
- 'connection_limit': vip1['connection_limit'],
- 'admin_state_up': vip1['admin_state_up']
- }
- vip = {'vip': self.api_vips.first()}
- neutronclient.create_vip({'vip': form_data}).AndReturn(vip)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.vip_create(self.request, **form_data)
- self.assertIsInstance(ret_val, api.lbaas.Vip)
-
- @test.create_stubs({neutronclient: ('list_vips',)})
- def test_vips_get(self):
- vips = {'vips': [{'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'address': '10.0.0.100',
- 'name': 'vip1name',
- 'description': 'vip1description',
- 'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
- 'protocol_port': '80',
- 'protocol': 'HTTP',
- 'pool_id': '8913dde8-4915-4b90-8d3e-b95eeedb0d49',
- 'connection_limit': '10',
- 'admin_state_up': True
- }, ]}
- neutronclient.list_vips().AndReturn(vips)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.vips_get(self.request)
- for v in ret_val:
- self.assertIsInstance(v, api.lbaas.Vip)
-
- @test.create_stubs({neutronclient: ('show_vip',)})
- def test_vip_get(self):
- vip = {'vip': {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'address': '10.0.0.100',
- 'name': 'vip1name',
- 'description': 'vip1description',
- 'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
- 'protocol_port': '80',
- 'protocol': 'HTTP',
- 'pool_id': '8913dde8-4915-4b90-8d3e-b95eeedb0d49',
- 'connection_limit': '10',
- 'admin_state_up': True
- }}
- neutronclient.show_vip(vip['vip']['id']).AndReturn(vip)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.vip_get(self.request, vip['vip']['id'])
- self.assertIsInstance(ret_val, api.lbaas.Vip)
-
- @test.create_stubs({neutronclient: ('update_vip',)})
- def test_vip_update(self):
- form_data = {'address': '10.0.0.100',
- 'name': 'vip1name',
- 'description': 'vip1description',
- 'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
- 'protocol_port': '80',
- 'protocol': 'HTTP',
- 'pool_id': '8913dde8-4915-4b90-8d3e-b95eeedb0d49',
- 'connection_limit': '10',
- 'admin_state_up': True
- }
-
- vip = {'vip': {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'address': '10.0.0.100',
- 'name': 'vip1name',
- 'description': 'vip1description',
- 'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
- 'protocol_port': '80',
- 'protocol': 'HTTP',
- 'pool_id': '8913dde8-4915-4b90-8d3e-b95eeedb0d49',
- 'connection_limit': '10',
- 'admin_state_up': True
- }}
- neutronclient.update_vip(vip['vip']['id'], form_data).AndReturn(vip)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.vip_update(self.request,
- vip['vip']['id'], **form_data)
- self.assertIsInstance(ret_val, api.lbaas.Vip)
-
- @test.create_stubs({neutronclient: ('create_pool',)})
- def test_pool_create(self):
- form_data = {'name': 'pool1name',
- 'description': 'pool1description',
- 'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
- 'protocol': 'HTTP',
- 'lb_method': 'ROUND_ROBIN',
- 'admin_state_up': True
- }
-
- pool = {'pool': {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'name': 'pool1name',
- 'description': 'pool1description',
- 'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
- 'protocol': 'HTTP',
- 'lb_method': 'ROUND_ROBIN',
- 'admin_state_up': True
- }}
- neutronclient.create_pool({'pool': form_data}).AndReturn(pool)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.pool_create(self.request, **form_data)
- self.assertIsInstance(ret_val, api.lbaas.Pool)
-
- @test.create_stubs({neutronclient: ('list_pools',)})
- def test_pools_get(self):
- pools = {'pools': [{
- 'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'name': 'pool1name',
- 'description': 'pool1description',
- 'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
- 'protocol': 'HTTP',
- 'lb_method': 'ROUND_ROBIN',
- 'admin_state_up': True}, ]}
- neutronclient.list_pools().AndReturn(pools)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.pools_get(self.request)
- for v in ret_val:
- self.assertIsInstance(v, api.lbaas.Pool)
-
- @test.create_stubs({neutronclient: ('show_pool',)})
- def test_pool_get(self):
- pool = {'pool': {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'name': 'pool1name',
- 'description': 'pool1description',
- 'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
- 'protocol': 'HTTP',
- 'lb_method': 'ROUND_ROBIN',
- 'admin_state_up': True
- }}
- neutronclient.show_pool(pool['pool']['id']).AndReturn(pool)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.pool_get(self.request, pool['pool']['id'])
- self.assertIsInstance(ret_val, api.lbaas.Pool)
-
- @test.create_stubs({neutronclient: ('update_pool',)})
- def test_pool_update(self):
- form_data = {'name': 'pool1name',
- 'description': 'pool1description',
- 'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
- 'protocol': 'HTTPS',
- 'lb_method': 'LEAST_CONNECTION',
- 'admin_state_up': True
- }
-
- pool = {'pool': {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'name': 'pool1name',
- 'description': 'pool1description',
- 'subnet_id': '12381d38-c3eb-4fee-9763-12de3338041e',
- 'protocol': 'HTTPS',
- 'lb_method': 'LEAST_CONNECTION',
- 'admin_state_up': True
- }}
- neutronclient.update_pool(pool['pool']['id'],
- form_data).AndReturn(pool)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.pool_update(self.request,
- pool['pool']['id'], **form_data)
- self.assertIsInstance(ret_val, api.lbaas.Pool)
-
- @test.create_stubs({neutronclient: ('create_health_monitor',)})
- def test_pool_health_monitor_create(self):
- form_data = {'type': 'PING',
- 'delay': '10',
- 'timeout': '10',
- 'max_retries': '10',
- 'admin_state_up': True
- }
- monitor = {'health_monitor': {
- 'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'type': 'PING',
- 'delay': '10',
- 'timeout': '10',
- 'max_retries': '10',
- 'admin_state_up': True}}
- neutronclient.create_health_monitor({
- 'health_monitor': form_data}).AndReturn(monitor)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.pool_health_monitor_create(
- self.request, **form_data)
- self.assertIsInstance(ret_val, api.lbaas.PoolMonitor)
-
- @test.create_stubs({neutronclient: ('list_health_monitors',)})
- def test_pool_health_monitors_get(self):
- monitors = {'health_monitors': [
- {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'type': 'PING',
- 'delay': '10',
- 'timeout': '10',
- 'max_retries': '10',
- 'http_method': 'GET',
- 'url_path': '/monitor',
- 'expected_codes': '200',
- 'admin_state_up': True}, ]}
-
- neutronclient.list_health_monitors().AndReturn(monitors)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.pool_health_monitors_get(self.request)
- for v in ret_val:
- self.assertIsInstance(v, api.lbaas.PoolMonitor)
-
- @test.create_stubs({neutronclient: ('show_health_monitor',)})
- def test_pool_health_monitor_get(self):
- monitor = {'health_monitor':
- {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'type': 'PING',
- 'delay': '10',
- 'timeout': '10',
- 'max_retries': '10',
- 'http_method': 'GET',
- 'url_path': '/monitor',
- 'expected_codes': '200',
- 'admin_state_up': True}}
- neutronclient.show_health_monitor(
- monitor['health_monitor']['id']).AndReturn(monitor)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.pool_health_monitor_get(
- self.request, monitor['health_monitor']['id'])
- self.assertIsInstance(ret_val, api.lbaas.PoolMonitor)
-
- @test.create_stubs({neutronclient: ('create_member', )})
- def test_member_create(self):
- form_data = {'pool_id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'address': '10.0.1.2',
- 'protocol_port': '80',
- 'weight': '10',
- 'admin_state_up': True
- }
-
- member = {'member':
- {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'pool_id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'address': '10.0.1.2',
- 'protocol_port': '80',
- 'weight': '10',
- 'admin_state_up': True}}
-
- neutronclient.create_member({'member': form_data}).AndReturn(member)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.member_create(self.request, **form_data)
- self.assertIsInstance(ret_val, api.lbaas.Member)
-
- @test.create_stubs({neutronclient: ('list_members',)})
- def test_members_get(self):
- members = {'members': [
- {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'pool_id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'address': '10.0.1.2',
- 'protocol_port': '80',
- 'weight': '10',
- 'admin_state_up': True
- }, ]}
- neutronclient.list_members().AndReturn(members)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.members_get(self.request)
- for v in ret_val:
- self.assertIsInstance(v, api.lbaas.Member)
-
- @test.create_stubs({neutronclient: ('show_member',)})
- def test_member_get(self):
- member = {'member': {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'pool_id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'address': '10.0.1.2',
- 'protocol_port': '80',
- 'weight': '10',
- 'admin_state_up': True}}
- neutronclient.show_member(member['member']['id']).AndReturn(member)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.member_get(self.request, member['member']['id'])
- self.assertIsInstance(ret_val, api.lbaas.Member)
-
- @test.create_stubs({neutronclient: ('update_member',)})
- def test_member_update(self):
- form_data = {'pool_id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'address': '10.0.1.4',
- 'protocol_port': '80',
- 'weight': '10',
- 'admin_state_up': True
- }
-
- member = {'member': {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'pool_id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'address': '10.0.1.2',
- 'protocol_port': '80',
- 'weight': '10',
- 'admin_state_up': True
- }}
-
- neutronclient.update_member(member['member']['id'],
- form_data).AndReturn(member)
- self.mox.ReplayAll()
-
- ret_val = api.lbaas.member_update(self.request,
- member['member']['id'], **form_data)
- self.assertIsInstance(ret_val, api.lbaas.Member)
diff --git a/openstack_dashboard/test/api_tests/network_tests.py b/openstack_dashboard/test/api_tests/network_tests.py
deleted file mode 100644
index c29f59b8..00000000
--- a/openstack_dashboard/test/api_tests/network_tests.py
+++ /dev/null
@@ -1,457 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import copy
-import itertools
-import uuid
-
-from django import http
-from mox import IsA
-
-from novaclient.v1_1.floating_ip_pools import FloatingIPPool
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class NetworkApiNovaTestBase(test.APITestCase):
- def setUp(self):
- super(NetworkApiNovaTestBase, self).setUp()
- self.mox.StubOutWithMock(api.base, 'is_service_enabled')
- api.base.is_service_enabled(IsA(http.HttpRequest), 'network') \
- .AndReturn(False)
-
-
-class NetworkApiNovaFloatingIpTests(NetworkApiNovaTestBase):
- def test_floating_ip_pools_list(self):
- pool_names = ['pool1', 'pool2']
- pools = [FloatingIPPool(None, {'name': pool}) for pool in pool_names]
- novaclient = self.stub_novaclient()
- novaclient.floating_ip_pools = self.mox.CreateMockAnything()
- novaclient.floating_ip_pools.list().AndReturn(pools)
- self.mox.ReplayAll()
-
- ret = api.network.floating_ip_pools_list(self.request)
- self.assertEqual([p.name for p in ret], pool_names)
-
- def test_floating_ip_list(self):
- fips = self.api_floating_ips.list()
- novaclient = self.stub_novaclient()
- novaclient.floating_ips = self.mox.CreateMockAnything()
- novaclient.floating_ips.list().AndReturn(fips)
- self.mox.ReplayAll()
-
- ret = api.network.tenant_floating_ip_list(self.request)
- for r, e in zip(ret, fips):
- for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']:
- self.assertEqual(r.__getattr__(attr), e.__getattr__(attr))
- self.assertEqual(r.port_id, e.instance_id)
-
- def test_floating_ip_get(self):
- fip = self.api_floating_ips.first()
- novaclient = self.stub_novaclient()
- novaclient.floating_ips = self.mox.CreateMockAnything()
- novaclient.floating_ips.get(fip.id).AndReturn(fip)
- self.mox.ReplayAll()
-
- ret = api.network.tenant_floating_ip_get(self.request, fip.id)
- for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']:
- self.assertEqual(ret.__getattr__(attr), fip.__getattr__(attr))
- self.assertEqual(ret.port_id, fip.instance_id)
-
- def test_floating_ip_allocate(self):
- pool_name = 'fip_pool'
- fip = self.api_floating_ips.first()
- novaclient = self.stub_novaclient()
- novaclient.floating_ips = self.mox.CreateMockAnything()
- novaclient.floating_ips.create(pool=pool_name).AndReturn(fip)
- self.mox.ReplayAll()
-
- ret = api.network.tenant_floating_ip_allocate(self.request, pool_name)
- for attr in ['id', 'ip', 'pool', 'fixed_ip', 'instance_id']:
- self.assertEqual(ret.__getattr__(attr), fip.__getattr__(attr))
- self.assertEqual(ret.port_id, fip.instance_id)
-
- def test_floating_ip_release(self):
- fip = self.api_floating_ips.first()
- novaclient = self.stub_novaclient()
- novaclient.floating_ips = self.mox.CreateMockAnything()
- novaclient.floating_ips.delete(fip.id)
- self.mox.ReplayAll()
-
- api.network.tenant_floating_ip_release(self.request, fip.id)
-
- def test_floating_ip_associate(self):
- server = api.nova.Server(self.servers.first(), self.request)
- floating_ip = self.floating_ips.first()
-
- novaclient = self.stub_novaclient()
- novaclient.floating_ips = self.mox.CreateMockAnything()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.get(server.id).AndReturn(server)
- novaclient.floating_ips.get(floating_ip.id).AndReturn(floating_ip)
- novaclient.servers.add_floating_ip(server.id, floating_ip.ip) \
- .AndReturn(server)
- self.mox.ReplayAll()
-
- api.network.floating_ip_associate(self.request,
- floating_ip.id,
- server.id)
-
- def test_floating_ip_disassociate(self):
- server = api.nova.Server(self.servers.first(), self.request)
- floating_ip = self.api_floating_ips.first()
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.floating_ips = self.mox.CreateMockAnything()
- novaclient.servers.get(server.id).AndReturn(server)
- novaclient.floating_ips.get(floating_ip.id).AndReturn(floating_ip)
- novaclient.servers.remove_floating_ip(server.id, floating_ip.ip) \
- .AndReturn(server)
- self.mox.ReplayAll()
-
- api.network.floating_ip_disassociate(self.request,
- floating_ip.id,
- server.id)
-
- def test_floating_ip_target_list(self):
- servers = self.servers.list()
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list().AndReturn(servers)
- self.mox.ReplayAll()
-
- targets = api.network.floating_ip_target_list(self.request)
- for target, server in zip(targets, servers):
- self.assertEqual(target.id, server.id)
- self.assertEqual(target.name, '%s (%s)' % (server.name, server.id))
-
- def test_floating_ip_target_get_by_instance(self):
- self.mox.ReplayAll()
- instance_id = self.servers.first().id
- ret = api.network.floating_ip_target_get_by_instance(self.request,
- instance_id)
- self.assertEqual(instance_id, ret)
-
-
-class NetworkApiNeutronTestBase(test.APITestCase):
- def setUp(self):
- super(NetworkApiNeutronTestBase, self).setUp()
- self.mox.StubOutWithMock(api.base, 'is_service_enabled')
- api.base.is_service_enabled(IsA(http.HttpRequest), 'network') \
- .AndReturn(True)
- self.qclient = self.stub_neutronclient()
-
-
-class NetworkApiNeutronSecurityGroupTests(NetworkApiNeutronTestBase):
-
- def setUp(self):
- super(NetworkApiNeutronSecurityGroupTests, self).setUp()
- self.sg_dict = dict([(sg['id'], sg['name']) for sg
- in self.api_q_secgroups.list()])
-
- def _cmp_sg_rule(self, exprule, retrule):
- self.assertEqual(exprule['id'], retrule.id)
- self.assertEqual(exprule['security_group_id'],
- retrule.parent_group_id)
- self.assertEqual(exprule['direction'], retrule.direction)
- self.assertEqual(exprule['ethertype'], retrule.ethertype)
- self.assertEqual(exprule['port_range_min'], retrule.from_port)
- self.assertEqual(exprule['port_range_max'], retrule.to_port)
- if (exprule['remote_ip_prefix'] is None and
- exprule['remote_group_id'] is None):
- expcidr = ('::/0' if exprule['ethertype'] == 'IPv6'
- else '0.0.0.0/0')
- else:
- expcidr = exprule['remote_ip_prefix']
- self.assertEqual(expcidr, retrule.ip_range.get('cidr'))
- self.assertEqual(self.sg_dict.get(exprule['remote_group_id']),
- retrule.group.get('name'))
-
- def _cmp_sg(self, exp_sg, ret_sg):
- self.assertEqual(exp_sg['id'], ret_sg.id)
- self.assertEqual(exp_sg['name'], ret_sg.name)
- exp_rules = exp_sg['security_group_rules']
- self.assertEqual(len(exp_rules), len(ret_sg.rules))
- for (exprule, retrule) in itertools.izip(exp_rules, ret_sg.rules):
- self._cmp_sg_rule(exprule, retrule)
-
- def test_security_group_list(self):
- sgs = self.api_q_secgroups.list()
- tenant_id = self.request.user.tenant_id
- # use deepcopy to ensure self.api_q_secgroups is not modified.
- self.qclient.list_security_groups(tenant_id=tenant_id) \
- .AndReturn({'security_groups': copy.deepcopy(sgs)})
- self.mox.ReplayAll()
-
- rets = api.network.security_group_list(self.request)
- self.assertEqual(len(sgs), len(rets))
- for (exp, ret) in itertools.izip(sgs, rets):
- self._cmp_sg(exp, ret)
-
- def test_security_group_get(self):
- secgroup = self.api_q_secgroups.first()
- sg_ids = set([secgroup['id']] +
- [rule['remote_group_id'] for rule
- in secgroup['security_group_rules']
- if rule['remote_group_id']])
- related_sgs = [sg for sg in self.api_q_secgroups.list()
- if sg['id'] in sg_ids]
- # use deepcopy to ensure self.api_q_secgroups is not modified.
- self.qclient.show_security_group(secgroup['id']) \
- .AndReturn({'security_group': copy.deepcopy(secgroup)})
- self.qclient.list_security_groups(id=sg_ids, fields=['id', 'name']) \
- .AndReturn({'security_groups': related_sgs})
- self.mox.ReplayAll()
- ret = api.network.security_group_get(self.request, secgroup['id'])
- self._cmp_sg(secgroup, ret)
-
- def test_security_group_create(self):
- secgroup = self.api_q_secgroups.list()[1]
- body = {'security_group':
- {'name': secgroup['name'],
- 'description': secgroup['description']}}
- self.qclient.create_security_group(body) \
- .AndReturn({'security_group': copy.deepcopy(secgroup)})
- self.mox.ReplayAll()
- ret = api.network.security_group_create(self.request, secgroup['name'],
- secgroup['description'])
- self._cmp_sg(secgroup, ret)
-
- def test_security_group_delete(self):
- secgroup = self.api_q_secgroups.first()
- self.qclient.delete_security_group(secgroup['id'])
- self.mox.ReplayAll()
- api.network.security_group_delete(self.request, secgroup['id'])
-
- def test_security_group_rule_create(self):
- sg_rule = [r for r in self.api_q_secgroup_rules.list()
- if r['protocol'] == 'tcp' and r['remote_ip_prefix']][0]
- sg_id = sg_rule['security_group_id']
- secgroup = [sg for sg in self.api_q_secgroups.list()
- if sg['id'] == sg_id][0]
-
- post_rule = copy.deepcopy(sg_rule)
- del post_rule['id']
- del post_rule['tenant_id']
- post_body = {'security_group_rule': post_rule}
- self.qclient.create_security_group_rule(post_body) \
- .AndReturn({'security_group_rule': copy.deepcopy(sg_rule)})
- self.qclient.list_security_groups(id=set([sg_id]),
- fields=['id', 'name']) \
- .AndReturn({'security_groups': [copy.deepcopy(secgroup)]})
- self.mox.ReplayAll()
-
- ret = api.network.security_group_rule_create(
- self.request, sg_rule['security_group_id'],
- sg_rule['direction'], sg_rule['ethertype'], sg_rule['protocol'],
- sg_rule['port_range_min'], sg_rule['port_range_max'],
- sg_rule['remote_ip_prefix'], sg_rule['remote_group_id'])
- self._cmp_sg_rule(sg_rule, ret)
-
- def test_security_group_rule_delete(self):
- sg_rule = self.api_q_secgroup_rules.first()
- self.qclient.delete_security_group_rule(sg_rule['id'])
- self.mox.ReplayAll()
- api.network.security_group_rule_delete(self.request, sg_rule['id'])
-
- def _get_instance(self, cur_sg_ids):
- instance_port = [p for p in self.api_ports.list()
- if p['device_owner'].startswith('compute:')][0]
- instance_id = instance_port['device_id']
- # Emulate an intance with two ports
- instance_ports = []
- for _i in range(2):
- p = copy.deepcopy(instance_port)
- p['id'] = str(uuid.uuid4())
- p['security_groups'] = cur_sg_ids
- instance_ports.append(p)
- return (instance_id, instance_ports)
-
- def test_server_security_groups(self):
- cur_sg_ids = [sg['id'] for sg in self.api_q_secgroups.list()[:2]]
- instance_id, instance_ports = self._get_instance(cur_sg_ids)
-
- self.qclient.list_ports(device_id=instance_id) \
- .AndReturn({'ports': instance_ports})
- secgroups = copy.deepcopy(self.api_q_secgroups.list())
- self.qclient.list_security_groups(id=set(cur_sg_ids)) \
- .AndReturn({'security_groups': secgroups})
- self.mox.ReplayAll()
-
- api.network.server_security_groups(self.request, instance_id)
-
- def test_server_update_security_groups(self):
- cur_sg_ids = [self.api_q_secgroups.first()['id']]
- new_sg_ids = [sg['id'] for sg in self.api_q_secgroups.list()[:2]]
- instance_id, instance_ports = self._get_instance(cur_sg_ids)
-
- self.qclient.list_ports(device_id=instance_id) \
- .AndReturn({'ports': instance_ports})
- for p in instance_ports:
- body = {'port': {'security_groups': new_sg_ids}}
- self.qclient.update_port(p['id'], body=body).AndReturn({'port': p})
- self.mox.ReplayAll()
- api.network.server_update_security_groups(
- self.request, instance_id, new_sg_ids)
-
- def test_security_group_backend(self):
- self.mox.ReplayAll()
- self.assertEqual(api.network.security_group_backend(self.request),
- 'neutron')
-
-
-class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
- def test_floating_ip_pools_list(self):
- search_opts = {'router:external': True}
- ext_nets = [n for n in self.api_networks.list()
- if n['router:external']]
- self.qclient.list_networks(**search_opts) \
- .AndReturn({'networks': ext_nets})
- self.mox.ReplayAll()
-
- rets = api.network.floating_ip_pools_list(self.request)
- for attr in ['id', 'name']:
- self.assertEqual([p.__getattr__(attr) for p in rets],
- [p[attr] for p in ext_nets])
-
- def test_floating_ip_list(self):
- fips = self.api_q_floating_ips.list()
- self.qclient.list_floatingips().AndReturn({'floatingips': fips})
- self.qclient.list_ports().AndReturn({'ports': self.api_ports.list()})
- self.mox.ReplayAll()
-
- rets = api.network.tenant_floating_ip_list(self.request)
- assoc_port = self.api_ports.list()[1]
- self.assertEqual(len(fips), len(rets))
- for ret, exp in zip(rets, fips):
- for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']:
- self.assertEqual(ret.__getattr__(attr), exp[attr])
- if exp['port_id']:
- dev_id = assoc_port['device_id'] if exp['port_id'] else None
- self.assertEqual(ret.instance_id, dev_id)
-
- def test_floating_ip_get_associated(self):
- fip = self.api_q_floating_ips.list()[1]
- assoc_port = self.api_ports.list()[1]
- self.qclient.show_floatingip(fip['id']).AndReturn({'floatingip': fip})
- self.qclient.show_port(assoc_port['id']) \
- .AndReturn({'port': assoc_port})
- self.mox.ReplayAll()
-
- ret = api.network.tenant_floating_ip_get(self.request, fip['id'])
- for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']:
- self.assertEqual(ret.__getattr__(attr), fip[attr])
- self.assertEqual(ret.instance_id, assoc_port['device_id'])
-
- def test_floating_ip_get_unassociated(self):
- fip = self.api_q_floating_ips.list()[0]
- self.qclient.show_floatingip(fip['id']).AndReturn({'floatingip': fip})
- self.mox.ReplayAll()
-
- ret = api.network.tenant_floating_ip_get(self.request, fip['id'])
- for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']:
- self.assertEqual(ret.__getattr__(attr), fip[attr])
- self.assertEqual(ret.instance_id, None)
-
- def test_floating_ip_allocate(self):
- ext_nets = [n for n in self.api_networks.list()
- if n['router:external']]
- ext_net = ext_nets[0]
- fip = self.api_q_floating_ips.first()
- self.qclient.create_floatingip(
- {'floatingip': {'floating_network_id': ext_net['id']}}) \
- .AndReturn({'floatingip': fip})
- self.mox.ReplayAll()
-
- ret = api.network.tenant_floating_ip_allocate(self.request,
- ext_net['id'])
- for attr in ['id', 'ip', 'pool', 'fixed_ip', 'port_id']:
- self.assertEqual(ret.__getattr__(attr), fip[attr])
- self.assertEqual(ret.instance_id, None)
-
- def test_floating_ip_release(self):
- fip = self.api_q_floating_ips.first()
- self.qclient.delete_floatingip(fip['id'])
- self.mox.ReplayAll()
-
- api.network.tenant_floating_ip_release(self.request, fip['id'])
-
- def test_floating_ip_associate(self):
- fip = self.api_q_floating_ips.list()[1]
- assoc_port = self.api_ports.list()[1]
- ip_address = assoc_port['fixed_ips'][0]['ip_address']
- target_id = '%s_%s' % (assoc_port['id'], ip_address)
- params = {'port_id': assoc_port['id'],
- 'fixed_ip_address': ip_address}
- self.qclient.update_floatingip(fip['id'],
- {'floatingip': params})
- self.mox.ReplayAll()
-
- api.network.floating_ip_associate(self.request, fip['id'], target_id)
-
- def test_floating_ip_disassociate(self):
- fip = self.api_q_floating_ips.list()[1]
- assoc_port = self.api_ports.list()[1]
- ip_address = assoc_port['fixed_ips'][0]['ip_address']
- target_id = '%s_%s' % (assoc_port['id'], ip_address)
- self.qclient.update_floatingip(fip['id'],
- {'floatingip': {'port_id': None}})
- self.mox.ReplayAll()
-
- api.network.floating_ip_disassociate(self.request, fip['id'],
- target_id)
-
- def _get_target_id(self, port):
- param = {'id': port['id'],
- 'addr': port['fixed_ips'][0]['ip_address']}
- return '%(id)s_%(addr)s' % param
-
- def _get_target_name(self, port):
- param = {'svrid': port['device_id'],
- 'addr': port['fixed_ips'][0]['ip_address']}
- return 'server_%(svrid)s: %(addr)s' % param
-
- def test_floating_ip_target_list(self):
- ports = self.api_ports.list()
- target_ports = [(self._get_target_id(p),
- self._get_target_name(p)) for p in ports
- if not p['device_owner'].startswith('network:')]
-
- self.qclient.list_ports().AndReturn({'ports': ports})
- servers = self.servers.list()
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- search_opts = {'project_id': self.request.user.tenant_id}
- novaclient.servers.list(True, search_opts).AndReturn(servers)
- self.mox.ReplayAll()
-
- rets = api.network.floating_ip_target_list(self.request)
- self.assertEqual(len(rets), len(target_ports))
- for ret, exp in zip(rets, target_ports):
- self.assertEqual(ret.id, exp[0])
- self.assertEqual(ret.name, exp[1])
-
- def test_floating_ip_target_get_by_instance(self):
- ports = self.api_ports.list()
- candidates = [p for p in ports if p['device_id'] == '1']
- search_opts = {'device_id': '1'}
- self.qclient.list_ports(**search_opts).AndReturn({'ports': candidates})
- self.mox.ReplayAll()
-
- ret = api.network.floating_ip_target_get_by_instance(self.request, '1')
- self.assertEqual(ret, self._get_target_id(candidates[0]))
diff --git a/openstack_dashboard/test/api_tests/neutron_tests.py b/openstack_dashboard/test/api_tests/neutron_tests.py
deleted file mode 100644
index 8ee10385..00000000
--- a/openstack_dashboard/test/api_tests/neutron_tests.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class NeutronApiTests(test.APITestCase):
- def test_network_list(self):
- networks = {'networks': self.api_networks.list()}
- subnets = {'subnets': self.api_subnets.list()}
-
- neutronclient = self.stub_neutronclient()
- neutronclient.list_networks().AndReturn(networks)
- neutronclient.list_subnets().AndReturn(subnets)
- self.mox.ReplayAll()
-
- ret_val = api.neutron.network_list(self.request)
- for n in ret_val:
- self.assertIsInstance(n, api.neutron.Network)
-
- def test_network_get(self):
- network = {'network': self.api_networks.first()}
- subnet = {'subnet': self.api_subnets.first()}
- network_id = self.api_networks.first()['id']
- subnet_id = self.api_networks.first()['subnets'][0]
-
- neutronclient = self.stub_neutronclient()
- neutronclient.show_network(network_id).AndReturn(network)
- neutronclient.show_subnet(subnet_id).AndReturn(subnet)
- self.mox.ReplayAll()
-
- ret_val = api.neutron.network_get(self.request, network_id)
- self.assertIsInstance(ret_val, api.neutron.Network)
-
- def test_network_create(self):
- network = {'network': self.api_networks.first()}
-
- neutronclient = self.stub_neutronclient()
- form_data = {'network': {'name': 'net1'}}
- neutronclient.create_network(body=form_data).AndReturn(network)
- self.mox.ReplayAll()
-
- ret_val = api.neutron.network_create(self.request, name='net1')
- self.assertIsInstance(ret_val, api.neutron.Network)
-
- def test_network_modify(self):
- network = {'network': self.api_networks.first()}
- network_id = self.api_networks.first()['id']
-
- neutronclient = self.stub_neutronclient()
- form_data = {'network': {'name': 'net1'}}
- neutronclient.update_network(network_id, body=form_data)\
- .AndReturn(network)
- self.mox.ReplayAll()
-
- ret_val = api.neutron.network_modify(self.request, network_id,
- name='net1')
- self.assertIsInstance(ret_val, api.neutron.Network)
-
- def test_network_delete(self):
- network_id = self.api_networks.first()['id']
-
- neutronclient = self.stub_neutronclient()
- neutronclient.delete_network(network_id)
- self.mox.ReplayAll()
-
- api.neutron.network_delete(self.request, network_id)
-
- def test_subnet_list(self):
- subnets = {'subnets': self.api_subnets.list()}
-
- neutronclient = self.stub_neutronclient()
- neutronclient.list_subnets().AndReturn(subnets)
- self.mox.ReplayAll()
-
- ret_val = api.neutron.subnet_list(self.request)
- for n in ret_val:
- self.assertIsInstance(n, api.neutron.Subnet)
-
- def test_subnet_get(self):
- subnet = {'subnet': self.api_subnets.first()}
- subnet_id = self.api_subnets.first()['id']
-
- neutronclient = self.stub_neutronclient()
- neutronclient.show_subnet(subnet_id).AndReturn(subnet)
- self.mox.ReplayAll()
-
- ret_val = api.neutron.subnet_get(self.request, subnet_id)
- self.assertIsInstance(ret_val, api.neutron.Subnet)
-
- def test_subnet_create(self):
- subnet_data = self.api_subnets.first()
- params = {'network_id': subnet_data['network_id'],
- 'tenant_id': subnet_data['tenant_id'],
- 'name': subnet_data['name'],
- 'cidr': subnet_data['cidr'],
- 'ip_version': subnet_data['ip_version'],
- 'gateway_ip': subnet_data['gateway_ip']}
-
- neutronclient = self.stub_neutronclient()
- neutronclient.create_subnet(body={'subnet': params})\
- .AndReturn({'subnet': subnet_data})
- self.mox.ReplayAll()
-
- ret_val = api.neutron.subnet_create(self.request, **params)
- self.assertIsInstance(ret_val, api.neutron.Subnet)
-
- def test_subnet_modify(self):
- subnet_data = self.api_subnets.first()
- subnet_id = subnet_data['id']
- params = {'name': subnet_data['name'],
- 'gateway_ip': subnet_data['gateway_ip']}
-
- neutronclient = self.stub_neutronclient()
- neutronclient.update_subnet(subnet_id, body={'subnet': params})\
- .AndReturn({'subnet': subnet_data})
- self.mox.ReplayAll()
-
- ret_val = api.neutron.subnet_modify(self.request, subnet_id, **params)
- self.assertIsInstance(ret_val, api.neutron.Subnet)
-
- def test_subnet_delete(self):
- subnet_id = self.api_subnets.first()['id']
-
- neutronclient = self.stub_neutronclient()
- neutronclient.delete_subnet(subnet_id)
- self.mox.ReplayAll()
-
- api.neutron.subnet_delete(self.request, subnet_id)
-
- def test_port_list(self):
- ports = {'ports': self.api_ports.list()}
-
- neutronclient = self.stub_neutronclient()
- neutronclient.list_ports().AndReturn(ports)
- self.mox.ReplayAll()
-
- ret_val = api.neutron.port_list(self.request)
- for p in ret_val:
- self.assertIsInstance(p, api.neutron.Port)
-
- def test_port_get(self):
- port = {'port': self.api_ports.first()}
- port_id = self.api_ports.first()['id']
-
- neutronclient = self.stub_neutronclient()
- neutronclient.show_port(port_id).AndReturn(port)
- self.mox.ReplayAll()
-
- ret_val = api.neutron.port_get(self.request, port_id)
- self.assertIsInstance(ret_val, api.neutron.Port)
-
- def test_port_create(self):
- port_data = self.api_ports.first()
- params = {'network_id': port_data['network_id'],
- 'tenant_id': port_data['tenant_id'],
- 'name': port_data['name'],
- 'device_id': port_data['device_id']}
-
- neutronclient = self.stub_neutronclient()
- neutronclient.create_port(body={'port': params})\
- .AndReturn({'port': port_data})
- self.mox.ReplayAll()
-
- ret_val = api.neutron.port_create(self.request, **params)
- self.assertIsInstance(ret_val, api.neutron.Port)
- self.assertEqual(ret_val.id, api.neutron.Port(port_data).id)
-
- def test_port_modify(self):
- port_data = self.api_ports.first()
- port_id = port_data['id']
- params = {'name': port_data['name'],
- 'device_id': port_data['device_id']}
-
- neutronclient = self.stub_neutronclient()
- neutronclient.update_port(port_id, body={'port': params})\
- .AndReturn({'port': port_data})
- self.mox.ReplayAll()
-
- ret_val = api.neutron.port_modify(self.request, port_id, **params)
- self.assertIsInstance(ret_val, api.neutron.Port)
- self.assertEqual(ret_val.id, api.neutron.Port(port_data).id)
-
- def test_port_delete(self):
- port_id = self.api_ports.first()['id']
-
- neutronclient = self.stub_neutronclient()
- neutronclient.delete_port(port_id)
- self.mox.ReplayAll()
-
- api.neutron.port_delete(self.request, port_id)
-
- def test_router_list(self):
- routers = {'routers': self.api_routers.list()}
-
- neutronclient = self.stub_neutronclient()
- neutronclient.list_routers().AndReturn(routers)
- self.mox.ReplayAll()
-
- ret_val = api.neutron.router_list(self.request)
- for n in ret_val:
- self.assertIsInstance(n, api.neutron.Router)
-
- def test_router_get(self):
- router = {'router': self.api_routers.first()}
- router_id = self.api_routers.first()['id']
-
- neutronclient = self.stub_neutronclient()
- neutronclient.show_router(router_id).AndReturn(router)
- self.mox.ReplayAll()
-
- ret_val = api.neutron.router_get(self.request, router_id)
- self.assertIsInstance(ret_val, api.neutron.Router)
-
- def test_router_create(self):
- router = {'router': self.api_routers.first()}
-
- neutronclient = self.stub_neutronclient()
- form_data = {'router': {'name': 'router1'}}
- neutronclient.create_router(body=form_data).AndReturn(router)
- self.mox.ReplayAll()
-
- ret_val = api.neutron.router_create(self.request, name='router1')
- self.assertIsInstance(ret_val, api.neutron.Router)
-
- def test_router_delete(self):
- router_id = self.api_routers.first()['id']
-
- neutronclient = self.stub_neutronclient()
- neutronclient.delete_router(router_id)
- self.mox.ReplayAll()
-
- api.neutron.router_delete(self.request, router_id)
-
- def test_router_add_interface(self):
- subnet_id = self.api_subnets.first()['id']
- router_id = self.api_routers.first()['id']
-
- neutronclient = self.stub_neutronclient()
- form_data = {'subnet_id': subnet_id}
- neutronclient.add_interface_router(
- router_id, form_data).AndReturn(None)
- self.mox.ReplayAll()
-
- api.neutron.router_add_interface(
- self.request, router_id, subnet_id=subnet_id)
-
- def test_router_remove_interface(self):
- router_id = self.api_routers.first()['id']
- fake_port = self.api_ports.first()['id']
-
- neutronclient = self.stub_neutronclient()
- neutronclient.remove_interface_router(
- router_id, {'port_id': fake_port})
- self.mox.ReplayAll()
-
- api.neutron.router_remove_interface(
- self.request, router_id, port_id=fake_port)
diff --git a/openstack_dashboard/test/api_tests/nova_tests.py b/openstack_dashboard/test/api_tests/nova_tests.py
deleted file mode 100644
index af45f9ee..00000000
--- a/openstack_dashboard/test/api_tests/nova_tests.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-# Copyright (c) 2012 X.commerce, a business unit of eBay Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from __future__ import absolute_import
-
-from django.conf import settings
-from django import http
-from django.test.utils import override_settings
-
-from mox import IsA
-from novaclient.v1_1 import servers
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class ServerWrapperTests(test.TestCase):
-
- def test_get_base_attribute(self):
- server = api.nova.Server(self.servers.first(), self.request)
- self.assertEqual(server.id, self.servers.first().id)
-
- def test_image_name(self):
- image = self.images.first()
- self.mox.StubOutWithMock(api.glance, 'image_get')
- api.glance.image_get(IsA(http.HttpRequest),
- image.id).AndReturn(image)
- self.mox.ReplayAll()
-
- server = api.nova.Server(self.servers.first(), self.request)
- self.assertEqual(server.image_name, image.name)
-
-
-class ComputeApiTests(test.APITestCase):
-
- def test_server_reboot(self):
- server = self.servers.first()
- HARDNESS = servers.REBOOT_HARD
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.get(server.id).AndReturn(server)
- novaclient.servers.reboot(server.id, HARDNESS)
- self.mox.ReplayAll()
-
- ret_val = api.nova.server_reboot(self.request, server.id)
- self.assertIsNone(ret_val)
-
- def test_server_soft_reboot(self):
- server = self.servers.first()
- HARDNESS = servers.REBOOT_SOFT
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.get(server.id).AndReturn(server)
- novaclient.servers.reboot(server.id, HARDNESS)
- self.mox.ReplayAll()
-
- ret_val = api.nova.server_reboot(self.request, server.id, HARDNESS)
- self.assertIsNone(ret_val)
-
- def test_server_vnc_console(self):
- server = self.servers.first()
- console = self.servers.vnc_console_data
- console_type = console["console"]["type"]
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.get_vnc_console(server.id,
- console_type).AndReturn(console)
- self.mox.ReplayAll()
-
- ret_val = api.nova.server_vnc_console(self.request,
- server.id,
- console_type)
- self.assertIsInstance(ret_val, api.nova.VNCConsole)
-
- def test_server_spice_console(self):
- server = self.servers.first()
- console = self.servers.spice_console_data
- console_type = console["console"]["type"]
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.get_spice_console(server.id,
- console_type).AndReturn(console)
- self.mox.ReplayAll()
-
- ret_val = api.nova.server_spice_console(self.request,
- server.id,
- console_type)
- self.assertIsInstance(ret_val, api.nova.SPICEConsole)
-
- def test_server_list(self):
- servers = self.servers.list()
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list(True, {'all_tenants': True}).AndReturn(servers)
- self.mox.ReplayAll()
-
- ret_val, has_more = api.nova.server_list(self.request,
- all_tenants=True)
- for server in ret_val:
- self.assertIsInstance(server, api.nova.Server)
-
- def test_server_list_pagination(self):
- page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 20)
- servers = self.servers.list()
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list(True,
- {'all_tenants': True,
- 'marker': None,
- 'limit': page_size + 1}).AndReturn(servers)
- self.mox.ReplayAll()
-
- ret_val, has_more = api.nova.server_list(self.request,
- {'marker': None,
- 'paginate': True},
- all_tenants=True)
- for server in ret_val:
- self.assertIsInstance(server, api.nova.Server)
- self.assertFalse(has_more)
-
- @override_settings(API_RESULT_PAGE_SIZE=1)
- def test_server_list_pagination_more(self):
- page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 1)
- servers = self.servers.list()
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.list(True,
- {'all_tenants': True,
- 'marker': None,
- 'limit': page_size + 1}) \
- .AndReturn(servers[:page_size + 1])
- self.mox.ReplayAll()
-
- ret_val, has_more = api.nova.server_list(self.request,
- {'marker': None,
- 'paginate': True},
- all_tenants=True)
- for server in ret_val:
- self.assertIsInstance(server, api.nova.Server)
- self.assertEquals(page_size, len(ret_val))
- self.assertTrue(has_more)
-
- def test_usage_get(self):
- novaclient = self.stub_novaclient()
- novaclient.usage = self.mox.CreateMockAnything()
- novaclient.usage.get(self.tenant.id,
- 'start',
- 'end').AndReturn(self.usages.first())
- self.mox.ReplayAll()
-
- ret_val = api.nova.usage_get(self.request, self.tenant.id,
- 'start', 'end')
- self.assertIsInstance(ret_val, api.nova.NovaUsage)
-
- def test_usage_list(self):
- usages = self.usages.list()
-
- novaclient = self.stub_novaclient()
- novaclient.usage = self.mox.CreateMockAnything()
- novaclient.usage.list('start', 'end', True).AndReturn(usages)
- self.mox.ReplayAll()
-
- ret_val = api.nova.usage_list(self.request, 'start', 'end')
- for usage in ret_val:
- self.assertIsInstance(usage, api.nova.NovaUsage)
-
- def test_server_get(self):
- server = self.servers.first()
-
- novaclient = self.stub_novaclient()
- novaclient.servers = self.mox.CreateMockAnything()
- novaclient.servers.get(server.id).AndReturn(server)
- self.mox.ReplayAll()
-
- ret_val = api.nova.server_get(self.request, server.id)
- self.assertIsInstance(ret_val, api.nova.Server)
-
- def test_absolute_limits_handle_unlimited(self):
- values = {"maxTotalCores": -1, "maxTotalInstances": 10}
- limits = self.mox.CreateMockAnything()
- limits.absolute = []
- for key, val in values.iteritems():
- limit = self.mox.CreateMockAnything()
- limit.name = key
- limit.value = val
- limits.absolute.append(limit)
-
- novaclient = self.stub_novaclient()
- novaclient.limits = self.mox.CreateMockAnything()
- novaclient.limits.get(reserved=True).AndReturn(limits)
- self.mox.ReplayAll()
-
- ret_val = api.nova.tenant_absolute_limits(self.request, reserved=True)
- expected_results = {"maxTotalCores": float("inf"),
- "maxTotalInstances": 10}
- for key in expected_results.keys():
- self.assertEquals(ret_val[key], expected_results[key])
diff --git a/openstack_dashboard/test/api_tests/swift_tests.py b/openstack_dashboard/test/api_tests/swift_tests.py
deleted file mode 100644
index 0e2c6e59..00000000
--- a/openstack_dashboard/test/api_tests/swift_tests.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from __future__ import absolute_import
-
-from mox import IsA
-
-from horizon import exceptions
-
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class SwiftApiTests(test.APITestCase):
- def test_swift_get_containers(self):
- containers = self.containers.list()
- cont_data = [c._apidict for c in containers]
- swift_api = self.stub_swiftclient()
- swift_api.get_account(limit=1001,
- marker=None,
- full_listing=True).AndReturn([{}, cont_data])
- self.mox.ReplayAll()
-
- (conts, more) = api.swift.swift_get_containers(self.request)
- self.assertEqual(len(conts), len(containers))
- self.assertFalse(more)
-
- def test_swift_create_duplicate_container(self):
- container = self.containers.first()
- swift_api = self.stub_swiftclient(expected_calls=2)
- # Check for existence, then create
- exc = self.exceptions.swift
- swift_api.head_container(container.name).AndRaise(exc)
- swift_api.put_container(container.name).AndReturn(container)
- self.mox.ReplayAll()
- # Verification handled by mox, no assertions needed.
- api.swift.swift_create_container(self.request, container.name)
-
- def test_swift_create_container(self):
- container = self.containers.first()
- swift_api = self.stub_swiftclient()
- swift_api.head_container(container.name).AndReturn(container)
- self.mox.ReplayAll()
- # Verification handled by mox, no assertions needed.
- with self.assertRaises(exceptions.AlreadyExists):
- api.swift.swift_create_container(self.request, container.name)
-
- def test_swift_get_objects(self):
- container = self.containers.first()
- objects = self.objects.list()
-
- swift_api = self.stub_swiftclient()
- swift_api.get_container(container.name,
- limit=1001,
- marker=None,
- prefix=None,
- delimiter='/',
- full_listing=True).AndReturn([{}, objects])
- self.mox.ReplayAll()
-
- (objs, more) = api.swift.swift_get_objects(self.request,
- container.name)
- self.assertEqual(len(objs), len(objects))
- self.assertFalse(more)
-
- def test_swift_upload_object(self):
- container = self.containers.first()
- obj = self.objects.first()
- fake_name = 'fake_object.jpg'
-
- class FakeFile(object):
- def __init__(self):
- self.name = fake_name
- self.data = obj.data
- self.size = len(obj.data)
-
- headers = {'X-Object-Meta-Orig-Filename': fake_name}
-
- swift_api = self.stub_swiftclient()
- swift_api.put_object(container.name,
- obj.name,
- IsA(FakeFile),
- headers=headers)
- self.mox.ReplayAll()
-
- api.swift.swift_upload_object(self.request,
- container.name,
- obj.name,
- FakeFile())
-
- def test_swift_object_exists(self):
- container = self.containers.first()
- obj = self.objects.first()
-
- swift_api = self.stub_swiftclient(expected_calls=2)
- swift_api.head_object(container.name, obj.name).AndReturn(container)
-
- exc = self.exceptions.swift
- swift_api.head_object(container.name, obj.name).AndRaise(exc)
- self.mox.ReplayAll()
-
- args = self.request, container.name, obj.name
- self.assertTrue(api.swift.swift_object_exists(*args))
- # Again, for a "non-existent" object
- self.assertFalse(api.swift.swift_object_exists(*args))
diff --git a/openstack_dashboard/test/api_tests/tuskar_tests.py b/openstack_dashboard/test/api_tests/tuskar_tests.py
deleted file mode 100644
index 59e0d805..00000000
--- a/openstack_dashboard/test/api_tests/tuskar_tests.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Red Hat, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from __future__ import absolute_import
-from openstack_dashboard import api
-from openstack_dashboard.test import helpers as test
-
-
-class TuskarApiTests(test.APITestCase):
- def test_resource_class_list(self):
- rcs = self.tuskar_resource_classes.list()
-
- tuskarclient = self.stub_tuskarclient()
- tuskarclient.resource_classes = self.mox.CreateMockAnything()
- tuskarclient.resource_classes.list().AndReturn(rcs)
- self.mox.ReplayAll()
-
- ret_val = api.tuskar.ResourceClass.list(self.request)
- for rc in ret_val:
- self.assertIsInstance(rc, api.tuskar.ResourceClass)
-
- def test_resource_class_get(self):
- rc = self.tuskar_resource_classes.first()
-
- tuskarclient = self.stub_tuskarclient()
- tuskarclient.resource_classes = self.mox.CreateMockAnything()
- tuskarclient.resource_classes.get(rc.id).AndReturn(rc)
- self.mox.ReplayAll()
-
- ret_val = api.tuskar.ResourceClass.get(self.request, rc.id)
- self.assertIsInstance(ret_val, api.tuskar.ResourceClass)
-
- def test_resource_class_flavor_counts(self):
- rc = self.tuskar_resource_classes.first()
- flavors = self.tuskar_flavors.list()
-
- tuskarclient = self.stub_tuskarclient()
- tuskarclient.flavors = self.mox.CreateMockAnything()
- tuskarclient.flavors.list(rc.id).AndReturn(flavors)
- self.mox.ReplayAll()
-
- for f in rc.list_flavors:
- self.assertIsInstance(f, api.tuskar.Flavor)
- self.assertEquals(2, len(rc.list_flavors))
-
- def test_resource_class_racks(self):
- rc = self.tuskar_resource_classes.first()
- r = self.tuskar_racks.first()
-
- tuskarclient = self.stub_tuskarclient()
- tuskarclient.racks = self.mox.CreateMockAnything()
- tuskarclient.racks.get(r.id).AndReturn(r)
- self.mox.ReplayAll()
-
- for rack in rc.list_racks:
- self.assertIsInstance(rack, api.tuskar.Rack)
- self.assertEquals(1, len(rc.list_racks))
-
- ## FIXME: we need to stub out the bare metal client, will
- ## be easier once the client is separated out a bit
- def test_resource_class_nodes(self):
- rc = self.tuskar_resource_classes.first()
- r = self.tuskar_racks.first()
-
- tuskarclient = self.stub_tuskarclient()
- tuskarclient.racks = self.mox.CreateMockAnything()
- tuskarclient.racks.get(r.id).AndReturn(r)
- self.mox.ReplayAll()
-
- for node in rc.nodes:
- self.assertIsInstance(node, api.tuskar.Node)
- self.assertEquals(4, len(rc.nodes))
-
- # TODO(create, delete operations)
-
- def test_flavor_template_list(self):
- templates = api.tuskar.FlavorTemplate.list(self.request)
- self.assertEquals(7, len(templates))
- for t in templates:
- self.assertIsInstance(t, api.tuskar.FlavorTemplate)
-
- def test_flavor_template_get(self):
- test_template = self.tuskar_flavor_templates.first()
- template = api.tuskar.FlavorTemplate.get(self.request,
- test_template.id)
- self.assertIsInstance(template, api.tuskar.FlavorTemplate)
- self.assertEquals(template.name, test_template.name)
diff --git a/openstack_dashboard/test/error_pages_urls.py b/openstack_dashboard/test/error_pages_urls.py
deleted file mode 100644
index c9f18178..00000000
--- a/openstack_dashboard/test/error_pages_urls.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from django.conf.urls import patterns
-
-from openstack_dashboard.urls import urlpatterns
-
-urlpatterns += patterns('',
- (r'^500/$', 'django.views.defaults.server_error')
-)
diff --git a/openstack_dashboard/test/helpers.py b/openstack_dashboard/test/helpers.py
deleted file mode 100644
index 1a6ad870..00000000
--- a/openstack_dashboard/test/helpers.py
+++ /dev/null
@@ -1,398 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from functools import wraps
-import os
-
-from django.conf import settings
-from django.contrib.auth.middleware import AuthenticationMiddleware
-from django.contrib.messages.storage import default_storage
-from django.core.handlers import wsgi
-from django import http
-from django.test.client import RequestFactory
-from django.utils.importlib import import_module
-from django.utils import unittest
-
-from cinderclient import client as cinder_client
-import glanceclient
-from heatclient import client as heat_client
-from keystoneclient.v2_0 import client as keystone_client
-from neutronclient.v2_0 import client as neutron_client
-from novaclient.v1_1 import client as nova_client
-from swiftclient import client as swift_client
-from tuskarclient.v1 import client as tuskar_client
-
-import httplib2
-import mox
-
-from openstack_auth import user
-from openstack_auth import utils
-
-from horizon import middleware
-from horizon.test import helpers as horizon_helpers
-
-from openstack_dashboard import api
-from openstack_dashboard import context_processors
-from openstack_dashboard.test.test_data.utils import load_test_data
-
-
-# Makes output of failing mox tests much easier to read.
-wsgi.WSGIRequest.__repr__ = lambda self: "<class 'django.http.HttpRequest'>"
-
-
-def create_stubs(stubs_to_create={}):
- if not isinstance(stubs_to_create, dict):
- raise TypeError("create_stub must be passed a dict, but a %s was "
- "given." % type(stubs_to_create).__name__)
-
- def inner_stub_out(fn):
- @wraps(fn)
- def instance_stub_out(self):
- for key in stubs_to_create:
- if not (isinstance(stubs_to_create[key], tuple) or
- isinstance(stubs_to_create[key], list)):
- raise TypeError("The values of the create_stub "
- "dict must be lists or tuples, but "
- "is a %s."
- % type(stubs_to_create[key]).__name__)
-
- for value in stubs_to_create[key]:
- self.mox.StubOutWithMock(key, value)
- return fn(self)
- return instance_stub_out
- return inner_stub_out
-
-
-class RequestFactoryWithMessages(RequestFactory):
- def get(self, *args, **kwargs):
- req = super(RequestFactoryWithMessages, self).get(*args, **kwargs)
- req.user = utils.get_user(req)
- req.session = []
- req._messages = default_storage(req)
- return req
-
- def post(self, *args, **kwargs):
- req = super(RequestFactoryWithMessages, self).post(*args, **kwargs)
- req.user = utils.get_user(req)
- req.session = []
- req._messages = default_storage(req)
- return req
-
-
-@unittest.skipIf(os.environ.get('SKIP_UNITTESTS', False),
- "The SKIP_UNITTESTS env variable is set.")
-class TestCase(horizon_helpers.TestCase):
- """
- Specialized base test case class for Horizon which gives access to
- numerous additional features:
-
- * A full suite of test data through various attached objects and
- managers (e.g. ``self.servers``, ``self.user``, etc.). See the
- docs for :class:`~horizon.tests.test_data.utils.TestData` for more
- information.
- * The ``mox`` mocking framework via ``self.mox``.
- * A set of request context data via ``self.context``.
- * A ``RequestFactory`` class which supports Django's ``contrib.messages``
- framework via ``self.factory``.
- * A ready-to-go request object via ``self.request``.
- * The ability to override specific time data controls for easier testing.
- * Several handy additional assertion methods.
- """
- def setUp(self):
- load_test_data(self)
- self.mox = mox.Mox()
- self.factory = RequestFactoryWithMessages()
- self.context = {'authorized_tenants': self.tenants.list()}
-
- def fake_conn_request(*args, **kwargs):
- raise Exception("An external URI request tried to escape through "
- "an httplib2 client. Args: %s, kwargs: %s"
- % (args, kwargs))
-
- self._real_conn_request = httplib2.Http._conn_request
- httplib2.Http._conn_request = fake_conn_request
-
- self._real_context_processor = context_processors.openstack
- context_processors.openstack = lambda request: self.context
-
- self._real_get_user = utils.get_user
- tenants = self.context['authorized_tenants']
- self.setActiveUser(id=self.user.id,
- token=self.token,
- username=self.user.name,
- tenant_id=self.tenant.id,
- service_catalog=self.service_catalog,
- authorized_tenants=tenants)
- self.request = http.HttpRequest()
- self.request.session = self.client._session()
- self.request.session['token'] = self.token.id
- middleware.HorizonMiddleware().process_request(self.request)
- AuthenticationMiddleware().process_request(self.request)
- os.environ["HORIZON_TEST_RUN"] = "True"
-
- def tearDown(self):
- self.mox.UnsetStubs()
- httplib2.Http._conn_request = self._real_conn_request
- context_processors.openstack = self._real_context_processor
- utils.get_user = self._real_get_user
- self.mox.VerifyAll()
- del os.environ["HORIZON_TEST_RUN"]
-
- def setActiveUser(self, id=None, token=None, username=None, tenant_id=None,
- service_catalog=None, tenant_name=None, roles=None,
- authorized_tenants=None, enabled=True):
- def get_user(request):
- return user.User(id=id,
- token=token,
- user=username,
- tenant_id=tenant_id,
- service_catalog=service_catalog,
- roles=roles,
- enabled=enabled,
- authorized_tenants=authorized_tenants,
- endpoint=settings.OPENSTACK_KEYSTONE_URL)
- utils.get_user = get_user
-
- def assertRedirectsNoFollow(self, response, expected_url):
- """
- Asserts that the given response issued a 302 redirect without
- processing the view which is redirected to.
- """
- assert (response.status_code / 100 == 3), \
- "The response did not return a redirect."
- self.assertEqual(response._headers.get('location', None),
- ('Location', settings.TESTSERVER + expected_url))
- self.assertEqual(response.status_code, 302)
-
- def assertNoFormErrors(self, response, context_name="form"):
- """
- Asserts that the response either does not contain a form in it's
- context, or that if it does, that form has no errors.
- """
- context = getattr(response, "context", {})
- if not context or context_name not in context:
- return True
- errors = response.context[context_name]._errors
- assert len(errors) == 0, \
- "Unexpected errors were found on the form: %s" % errors
-
- def assertFormErrors(self, response, count=0, message=None,
- context_name="form"):
- """
- Asserts that the response does contain a form in it's
- context, and that form has errors, if count were given,
- it must match the exact numbers of errors
- """
- context = getattr(response, "context", {})
- assert (context and context_name in context), \
- "The response did not contain a form."
- errors = response.context[context_name]._errors
- if count:
- assert len(errors) == count, \
- "%d errors were found on the form, %d expected" % \
- (len(errors), count)
- if message and message not in unicode(errors):
- self.fail("Expected message not found, instead found: %s"
- % ["%s: %s" % (key, [e for e in field_errors]) for
- (key, field_errors) in errors.items()])
- else:
- assert len(errors) > 0, "No errors were found on the form"
-
-
-class BaseAdminViewTests(TestCase):
- """
- A ``TestCase`` subclass which sets an active user with the "admin" role
- for testing admin-only views and functionality.
- """
- def setActiveUser(self, *args, **kwargs):
- if "roles" not in kwargs:
- kwargs['roles'] = [self.roles.admin._info]
- super(BaseAdminViewTests, self).setActiveUser(*args, **kwargs)
-
- def setSessionValues(self, **kwargs):
- settings.SESSION_ENGINE = 'django.contrib.sessions.backends.file'
- engine = import_module(settings.SESSION_ENGINE)
- store = engine.SessionStore()
- for key in kwargs:
- store[key] = kwargs[key]
- self.request.session[key] = kwargs[key]
- store.save()
- self.session = store
- self.client.cookies[settings.SESSION_COOKIE_NAME] = store.session_key
-
-
-class APITestCase(TestCase):
- """
- The ``APITestCase`` class is for use with tests which deal with the
- underlying clients rather than stubbing out the
- openstack_dashboard.api.* methods.
- """
- def setUp(self):
- super(APITestCase, self).setUp()
-
- def fake_keystoneclient(request, admin=False):
- """
- Wrapper function which returns the stub keystoneclient. Only
- necessary because the function takes too many arguments to
- conveniently be a lambda.
- """
- return self.stub_keystoneclient()
-
- # Store the original clients
- self._original_glanceclient = api.glance.glanceclient
- self._original_keystoneclient = api.keystone.keystoneclient
- self._original_novaclient = api.nova.novaclient
- self._original_neutronclient = api.neutron.neutronclient
- self._original_cinderclient = api.cinder.cinderclient
- self._original_heatclient = api.heat.heatclient
- self._original_tuskarclient = api.tuskar.tuskarclient
-
- # Replace the clients with our stubs.
- api.glance.glanceclient = lambda request: self.stub_glanceclient()
- api.keystone.keystoneclient = fake_keystoneclient
- api.nova.novaclient = lambda request: self.stub_novaclient()
- api.neutron.neutronclient = lambda request: self.stub_neutronclient()
- api.cinder.cinderclient = lambda request: self.stub_cinderclient()
- api.heat.heatclient = lambda request: self.stub_heatclient()
- api.tuskar.tuskarclient = lambda request: self.stub_tuskarclient()
-
- def tearDown(self):
- super(APITestCase, self).tearDown()
- api.glance.glanceclient = self._original_glanceclient
- api.nova.novaclient = self._original_novaclient
- api.keystone.keystoneclient = self._original_keystoneclient
- api.neutron.neutronclient = self._original_neutronclient
- api.cinder.cinderclient = self._original_cinderclient
- api.heat.heatclient = self._original_heatclient
- api.tuskar.tuskarclient = self._original_tuskarclient
-
- def stub_novaclient(self):
- if not hasattr(self, "novaclient"):
- self.mox.StubOutWithMock(nova_client, 'Client')
- self.novaclient = self.mox.CreateMock(nova_client.Client)
- return self.novaclient
-
- def stub_cinderclient(self):
- if not hasattr(self, "cinderclient"):
- self.mox.StubOutWithMock(cinder_client, 'Client')
- self.cinderclient = self.mox.CreateMock(cinder_client.Client)
- return self.cinderclient
-
- def stub_keystoneclient(self):
- if not hasattr(self, "keystoneclient"):
- self.mox.StubOutWithMock(keystone_client, 'Client')
- # NOTE(saschpe): Mock properties, MockObject.__init__ ignores them:
- keystone_client.Client.auth_token = 'foo'
- keystone_client.Client.service_catalog = None
- keystone_client.Client.tenant_id = '1'
- keystone_client.Client.tenant_name = 'tenant_1'
- self.keystoneclient = self.mox.CreateMock(keystone_client.Client)
- return self.keystoneclient
-
- def stub_glanceclient(self):
- if not hasattr(self, "glanceclient"):
- self.mox.StubOutWithMock(glanceclient, 'Client')
- self.glanceclient = self.mox.CreateMock(glanceclient.Client)
- return self.glanceclient
-
- def stub_neutronclient(self):
- if not hasattr(self, "neutronclient"):
- self.mox.StubOutWithMock(neutron_client, 'Client')
- self.neutronclient = self.mox.CreateMock(neutron_client.Client)
- return self.neutronclient
-
- def stub_swiftclient(self, expected_calls=1):
- if not hasattr(self, "swiftclient"):
- self.mox.StubOutWithMock(swift_client, 'Connection')
- self.swiftclient = self.mox.CreateMock(swift_client.Connection)
- while expected_calls:
- swift_client.Connection(None,
- mox.IgnoreArg(),
- None,
- preauthtoken=mox.IgnoreArg(),
- preauthurl=mox.IgnoreArg(),
- auth_version="2.0") \
- .AndReturn(self.swiftclient)
- expected_calls -= 1
- return self.swiftclient
-
- def stub_heatclient(self):
- if not hasattr(self, "heatclient"):
- self.mox.StubOutWithMock(heat_client, 'Client')
- self.heatclient = self.mox.CreateMock(heat_client.Client)
- return self.heatclient
-
- def stub_tuskarclient(self):
- if not hasattr(self, "tuskarclient"):
- self.mox.StubOutWithMock(tuskar_client, 'Client')
- self.tuskarclient = self.mox.CreateMock(tuskar_client.Client)
- return self.tuskarclient
-
-
-@unittest.skipUnless(os.environ.get('WITH_SELENIUM', False),
- "The WITH_SELENIUM env variable is not set.")
-class SeleniumTestCase(horizon_helpers.SeleniumTestCase):
-
- def setUp(self):
- super(SeleniumTestCase, self).setUp()
-
- load_test_data(self)
- self.mox = mox.Mox()
-
- self._real_get_user = utils.get_user
- self.setActiveUser(id=self.user.id,
- token=self.token,
- username=self.user.name,
- tenant_id=self.tenant.id,
- service_catalog=self.service_catalog,
- authorized_tenants=self.tenants.list())
- os.environ["HORIZON_TEST_RUN"] = "True"
-
- def tearDown(self):
- self.mox.UnsetStubs()
- utils.get_user = self._real_get_user
- self.mox.VerifyAll()
- del os.environ["HORIZON_TEST_RUN"]
-
- def setActiveUser(self, id=None, token=None, username=None, tenant_id=None,
- service_catalog=None, tenant_name=None, roles=None,
- authorized_tenants=None, enabled=True):
- def get_user(request):
- return user.User(id=id,
- token=token,
- user=username,
- tenant_id=tenant_id,
- service_catalog=service_catalog,
- roles=roles,
- enabled=enabled,
- authorized_tenants=authorized_tenants,
- endpoint=settings.OPENSTACK_KEYSTONE_URL)
- utils.get_user = get_user
-
-
-class SeleniumAdminTestCase(SeleniumTestCase):
- """
- A ``TestCase`` subclass which sets an active user with the "admin" role
- for testing admin-only views and functionality.
- """
- def setActiveUser(self, *args, **kwargs):
- if "roles" not in kwargs:
- kwargs['roles'] = [self.roles.admin._info]
- super(SeleniumAdminTestCase, self).setActiveUser(*args, **kwargs)
diff --git a/openstack_dashboard/test/settings.py b/openstack_dashboard/test/settings.py
deleted file mode 100644
index a4ee5ea6..00000000
--- a/openstack_dashboard/test/settings.py
+++ /dev/null
@@ -1,138 +0,0 @@
-import os
-
-from django.utils.translation import ugettext_lazy as _
-
-from horizon.test.settings import * # noqa
-from horizon.utils.secret_key import generate_or_read_from_file
-
-from openstack_dashboard.exceptions import NOT_FOUND
-from openstack_dashboard.exceptions import RECOVERABLE
-from openstack_dashboard.exceptions import UNAUTHORIZED
-
-
-TEST_DIR = os.path.dirname(os.path.abspath(__file__))
-ROOT_PATH = os.path.abspath(os.path.join(TEST_DIR, ".."))
-
-SECRET_KEY = generate_or_read_from_file(os.path.join(TEST_DIR,
- '.secret_key_store'))
-ROOT_URLCONF = 'openstack_dashboard.urls'
-TEMPLATE_DIRS = (
- os.path.join(TEST_DIR, 'templates'),
-)
-
-TEMPLATE_CONTEXT_PROCESSORS += (
- 'openstack_dashboard.context_processors.openstack',
-)
-
-INSTALLED_APPS = (
- 'django.contrib.contenttypes',
- 'django.contrib.auth',
- 'django.contrib.sessions',
- 'django.contrib.staticfiles',
- 'django.contrib.messages',
- 'django.contrib.humanize',
- 'django_nose',
- 'openstack_auth',
- 'compressor',
- 'horizon',
- 'openstack_dashboard',
- 'openstack_dashboard.dashboards.project',
- 'openstack_dashboard.dashboards.admin',
- 'openstack_dashboard.dashboards.infrastructure',
- 'openstack_dashboard.dashboards.settings',
-)
-
-AUTHENTICATION_BACKENDS = ('openstack_auth.backend.KeystoneBackend',)
-
-SITE_BRANDING = 'OpenStack'
-
-HORIZON_CONFIG = {
- 'dashboards': ('project', 'admin', 'infrastructure', 'settings'),
- 'default_dashboard': 'project',
- "password_validator": {
- "regex": '^.{8,18}$',
- "help_text": _("Password must be between 8 and 18 characters.")
- },
- 'user_home': None,
- 'help_url': "http://docs.openstack.org",
- 'exceptions': {'recoverable': RECOVERABLE,
- 'not_found': NOT_FOUND,
- 'unauthorized': UNAUTHORIZED},
-}
-
-# Set to True to allow users to upload images to glance via Horizon server.
-# When enabled, a file form field will appear on the create image form.
-# See documentation for deployment considerations.
-HORIZON_IMAGES_ALLOW_UPLOAD = True
-
-AVAILABLE_REGIONS = [
- ('http://localhost:5000/v2.0', 'local'),
- ('http://remote:5000/v2.0', 'remote'),
-]
-
-OPENSTACK_KEYSTONE_URL = "http://localhost:5000/v2.0"
-OPENSTACK_KEYSTONE_DEFAULT_ROLE = "Member"
-
-OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True
-OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = 'test_domain'
-
-OPENSTACK_KEYSTONE_BACKEND = {
- 'name': 'native',
- 'can_edit_user': True,
- 'can_edit_group': True,
- 'can_edit_project': True,
- 'can_edit_domain': True,
- 'can_edit_role': True
-}
-
-OPENSTACK_NEUTRON_NETWORK = {
- 'enable_lb': True
-}
-
-OPENSTACK_HYPERVISOR_FEATURES = {
- 'can_set_mount_point': True,
-
- # NOTE: as of Grizzly this is not yet supported in Nova so enabling this
- # setting will not do anything useful
- 'can_encrypt_volumes': False
-}
-
-LOGGING['loggers']['openstack_dashboard'] = {
- 'handlers': ['test'],
- 'propagate': False,
-}
-
-SECURITY_GROUP_RULES = {
- 'all_tcp': {
- 'name': 'ALL TCP',
- 'ip_protocol': 'tcp',
- 'from_port': '1',
- 'to_port': '65535',
- },
- 'http': {
- 'name': 'HTTP',
- 'ip_protocol': 'tcp',
- 'from_port': '80',
- 'to_port': '80',
- },
-}
-
-NOSE_ARGS = ['--nocapture',
- '--nologcapture',
- '--cover-package=openstack_dashboard',
- '--cover-inclusive',
- '--all-modules']
-
-# FIXME: this will eventually be unneeded when the parameter is removed
-# from local settings and api/tuskar.py
-TUSKAR_ENDPOINT_URL = "http://127.0.0.1:6385"
-NOVA_BAREMETAL_CREDS = {
- 'user': 'admin',
- 'password': 'admin_password_here',
- 'tenant': 'admin',
- 'auth_url': 'http://localhost:5001/v2.0/',
- 'bypass_url': 'http://localhost:9774/v2/692567cd99f84f5d8f26ec23ff0ba460'
-}
-OVERCLOUD_AUTH_URL = 'http://127.0.0.1:5000/v2.0'
-OVERCLOUD_USERNAME = 'admin'
-OVERCLOUD_PASSWORD = 'password'
diff --git a/openstack_dashboard/test/templates/404.html b/openstack_dashboard/test/templates/404.html
deleted file mode 100644
index 15f0063e..00000000
--- a/openstack_dashboard/test/templates/404.html
+++ /dev/null
@@ -1 +0,0 @@
-404 NOT FOUND
diff --git a/openstack_dashboard/test/templates/500.html b/openstack_dashboard/test/templates/500.html
deleted file mode 100644
index ab146d75..00000000
--- a/openstack_dashboard/test/templates/500.html
+++ /dev/null
@@ -1 +0,0 @@
-500 ERROR
diff --git a/openstack_dashboard/test/templates/_tab.html b/openstack_dashboard/test/templates/_tab.html
deleted file mode 100644
index e336d411..00000000
--- a/openstack_dashboard/test/templates/_tab.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ tab.name }}
diff --git a/openstack_dashboard/test/templates/base-sidebar.html b/openstack_dashboard/test/templates/base-sidebar.html
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/test/templates/base-sidebar.html
+++ /dev/null
diff --git a/openstack_dashboard/test/templates/registration/login.html b/openstack_dashboard/test/templates/registration/login.html
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/test/templates/registration/login.html
+++ /dev/null
diff --git a/openstack_dashboard/test/templates/tab_group.html b/openstack_dashboard/test/templates/tab_group.html
deleted file mode 100644
index 94b2e517..00000000
--- a/openstack_dashboard/test/templates/tab_group.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ tab_group.render }}
diff --git a/openstack_dashboard/test/templates/workflow.html b/openstack_dashboard/test/templates/workflow.html
deleted file mode 100644
index 02ec6658..00000000
--- a/openstack_dashboard/test/templates/workflow.html
+++ /dev/null
@@ -1 +0,0 @@
-{{ workflow.render }}
diff --git a/openstack_dashboard/test/test_data/__init__.py b/openstack_dashboard/test/test_data/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/test/test_data/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/test/test_data/cinder_data.py b/openstack_dashboard/test/test_data/cinder_data.py
deleted file mode 100644
index e70a2044..00000000
--- a/openstack_dashboard/test/test_data/cinder_data.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from cinderclient.v1 import quotas
-from openstack_dashboard.api.base import Quota
-from openstack_dashboard.api.base import QuotaSet as QuotaSetWrapper
-from openstack_dashboard.usage.quotas import QuotaUsage
-
-from openstack_dashboard.test.test_data.utils import TestDataContainer
-
-
-def data(TEST):
- TEST.cinder_quotas = TestDataContainer()
- TEST.cinder_quota_usages = TestDataContainer()
-
- # Quota Sets
- quota_data = dict(volumes='1',
- snapshots='1',
- gigabytes='1000')
- quota = quotas.QuotaSet(quotas.QuotaSetManager(None), quota_data)
- #TEST.quotas.cinder = QuotaSetWrapper(quota)
- TEST.cinder_quotas.add(QuotaSetWrapper(quota))
-
- # Quota Usages
- quota_usage_data = {'gigabytes': {'used': 0,
- 'quota': 1000},
- 'instances': {'used': 0,
- 'quota': 10},
- 'snapshots': {'used': 0,
- 'quota': 10}}
- quota_usage = QuotaUsage()
- for k, v in quota_usage_data.items():
- quota_usage.add_quota(Quota(k, v['quota']))
- quota_usage.tally(k, v['used'])
-
- TEST.cinder_quota_usages.add(quota_usage)
diff --git a/openstack_dashboard/test/test_data/exceptions.py b/openstack_dashboard/test/test_data/exceptions.py
deleted file mode 100644
index 4dc35866..00000000
--- a/openstack_dashboard/test/test_data/exceptions.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from cinderclient import exceptions as cinder_exceptions
-import glanceclient.exc as glance_exceptions
-from keystoneclient import exceptions as keystone_exceptions
-from neutronclient.common import exceptions as neutron_exceptions
-from novaclient import exceptions as nova_exceptions
-from swiftclient import client as swift_exceptions
-
-from openstack_dashboard.test.test_data.utils import TestDataContainer
-
-
-def create_stubbed_exception(cls, status_code=500):
- msg = "Expected failure."
-
- def fake_init_exception(self, code, message, **kwargs):
- self.code = code
- self.message = message
-
- def fake_str(self):
- return str(self.message)
-
- def fake_unicode(self):
- return unicode(self.message)
-
- cls.__init__ = fake_init_exception
- cls.__str__ = fake_str
- cls.__unicode__ = fake_unicode
- cls.silence_logging = True
- return cls(status_code, msg)
-
-
-def data(TEST):
- TEST.exceptions = TestDataContainer()
-
- unauth = keystone_exceptions.Unauthorized
- TEST.exceptions.keystone_unauthorized = create_stubbed_exception(unauth)
-
- keystone_exception = keystone_exceptions.ClientException
- TEST.exceptions.keystone = create_stubbed_exception(keystone_exception)
-
- nova_exception = nova_exceptions.ClientException
- TEST.exceptions.nova = create_stubbed_exception(nova_exception)
-
- nova_unauth = nova_exceptions.Unauthorized
- TEST.exceptions.nova_unauthorized = create_stubbed_exception(nova_unauth)
-
- glance_exception = glance_exceptions.ClientException
- TEST.exceptions.glance = create_stubbed_exception(glance_exception)
-
- neutron_exception = neutron_exceptions.NeutronClientException
- TEST.exceptions.neutron = create_stubbed_exception(neutron_exception)
-
- swift_exception = swift_exceptions.ClientException
- TEST.exceptions.swift = create_stubbed_exception(swift_exception)
-
- cinder_exception = cinder_exceptions.BadRequest
- TEST.exceptions.cinder = create_stubbed_exception(cinder_exception)
diff --git a/openstack_dashboard/test/test_data/glance_data.py b/openstack_dashboard/test/test_data/glance_data.py
deleted file mode 100644
index 1cd97e51..00000000
--- a/openstack_dashboard/test/test_data/glance_data.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from glanceclient.v1.images import Image
-from glanceclient.v1.images import ImageManager
-
-from openstack_dashboard.test.test_data.utils import TestDataContainer
-
-
-def data(TEST):
- TEST.images = TestDataContainer()
- TEST.snapshots = TestDataContainer()
-
- # Snapshots
- snapshot_dict = {'name': u'snapshot',
- 'container_format': u'ami',
- 'id': 3,
- 'status': "active",
- 'owner': TEST.tenant.id,
- 'properties': {'image_type': u'snapshot'},
- 'is_public': False,
- 'protected': False}
- snapshot_dict_no_owner = {'name': u'snapshot 2',
- 'container_format': u'ami',
- 'id': 4,
- 'status': "active",
- 'owner': None,
- 'properties': {'image_type': u'snapshot'},
- 'is_public': False,
- 'protected': False}
- snapshot_dict_queued = {'name': u'snapshot 2',
- 'container_format': u'ami',
- 'id': 5,
- 'status': "queued",
- 'owner': TEST.tenant.id,
- 'properties': {'image_type': u'snapshot'},
- 'is_public': False,
- 'protected': False}
- snapshot = Image(ImageManager(None), snapshot_dict)
- TEST.snapshots.add(snapshot)
- snapshot = Image(ImageManager(None), snapshot_dict_no_owner)
- TEST.snapshots.add(snapshot)
- snapshot = Image(ImageManager(None), snapshot_dict_queued)
- TEST.snapshots.add(snapshot)
-
- # Images
- image_dict = {'id': '007e7d55-fe1e-4c5c-bf08-44b4a4964822',
- 'name': 'public_image',
- 'status': "active",
- 'size': 20 * 1024 ** 3,
- 'owner': TEST.tenant.id,
- 'container_format': 'novaImage',
- 'properties': {'image_type': u'image'},
- 'is_public': True,
- 'protected': False}
- public_image = Image(ImageManager(None), image_dict)
-
- image_dict = {'id': 'a001c047-22f8-47d0-80a1-8ec94a9524fe',
- 'name': 'private_image',
- 'status': "active",
- 'size': 10 * 1024 ** 2,
- 'owner': TEST.tenant.id,
- 'container_format': 'aki',
- 'is_public': False,
- 'protected': False}
- private_image = Image(ImageManager(None), image_dict)
-
- image_dict = {'id': 'd6936c86-7fec-474a-85c5-5e467b371c3c',
- 'name': 'protected_images',
- 'status': "active",
- 'owner': TEST.tenant.id,
- 'size': 2 * 1024 ** 3,
- 'container_format': 'novaImage',
- 'properties': {'image_type': u'image'},
- 'is_public': True,
- 'protected': True}
- protected_image = Image(ImageManager(None), image_dict)
-
- image_dict = {'id': '278905a6-4b52-4d1e-98f9-8c57bb25ba32',
- 'name': 'public_image 2',
- 'status': "active",
- 'size': 5 * 1024 ** 3,
- 'owner': TEST.tenant.id,
- 'container_format': 'novaImage',
- 'properties': {'image_type': u'image'},
- 'is_public': True,
- 'protected': False}
- public_image2 = Image(ImageManager(None), image_dict)
-
- image_dict = {'id': '710a1acf-a3e3-41dd-a32d-5d6b6c86ea10',
- 'name': 'private_image 2',
- 'status': "active",
- 'size': 30 * 1024 ** 3,
- 'owner': TEST.tenant.id,
- 'container_format': 'aki',
- 'is_public': False,
- 'protected': False}
- private_image2 = Image(ImageManager(None), image_dict)
-
- image_dict = {'id': '7cd892fd-5652-40f3-a450-547615680132',
- 'name': 'private_image 3',
- 'status': "active",
- 'size': 2 * 1024 ** 3,
- 'owner': TEST.tenant.id,
- 'container_format': 'aki',
- 'is_public': False,
- 'protected': False}
- private_image3 = Image(ImageManager(None), image_dict)
-
- # A shared image. Not public and not local tenant.
- image_dict = {'id': 'c8756975-7a3b-4e43-b7f7-433576112849',
- 'name': 'shared_image 1',
- 'status': "active",
- 'size': 8 * 1024 ** 3,
- 'owner': 'someothertenant',
- 'container_format': 'aki',
- 'is_public': False,
- 'protected': False}
- shared_image1 = Image(ImageManager(None), image_dict)
-
- # "Official" image. Public and tenant matches an entry
- # in IMAGES_LIST_FILTER_TENANTS.
- image_dict = {'id': 'f448704f-0ce5-4d34-8441-11b6581c6619',
- 'name': 'official_image 1',
- 'status': "active",
- 'size': 2 * 1024 ** 3,
- 'owner': 'officialtenant',
- 'container_format': 'aki',
- 'is_public': True,
- 'protected': False}
- official_image1 = Image(ImageManager(None), image_dict)
-
- TEST.images.add(public_image, private_image, protected_image,
- public_image2, private_image2, private_image3,
- shared_image1, official_image1)
diff --git a/openstack_dashboard/test/test_data/heat_data.py b/openstack_dashboard/test/test_data/heat_data.py
deleted file mode 100644
index b05f3ff5..00000000
--- a/openstack_dashboard/test/test_data/heat_data.py
+++ /dev/null
@@ -1,340 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# 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 heatclient.v1.stacks import Stack
-from heatclient.v1.stacks import StackManager
-
-from openstack_dashboard.test.test_data.utils import TestDataContainer
-
-
-# A slightly hacked up copy of a sample cloudformation template for testing.
-TEMPLATE = """
-{
-"AWSTemplateFormatVersion": "2010-09-09",
-"Description": "AWS CloudFormation Sample Template.",
-"Parameters": {
-"KeyName": {
-"Description": "Name of an EC2 KeyPair to enable SSH access to the instances",
-"Type": "String"
-},
-"InstanceType": {
-"Description": "WebServer EC2 instance type",
-"Type": "String",
-"Default": "m1.small",
-"AllowedValues": [
-"m1.tiny",
-"m1.small",
-"m1.medium",
-"m1.large",
-"m1.xlarge"
-],
-"ConstraintDescription": "must be a valid EC2 instance type."
-},
-"DBName": {
-"Default": "wordpress",
-"Description": "The WordPress database name",
-"Type": "String",
-"MinLength": "1",
-"MaxLength": "64",
-"AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
-"ConstraintDescription": "must begin with a letter and..."
-},
-"DBUsername": {
-"Default": "admin",
-"NoEcho": "true",
-"Description": "The WordPress database admin account username",
-"Type": "String",
-"MinLength": "1",
-"MaxLength": "16",
-"AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
-"ConstraintDescription": "must begin with a letter and..."
-},
-"DBPassword": {
-"Default": "admin",
-"NoEcho": "true",
-"Description": "The WordPress database admin account password",
-"Type": "String",
-"MinLength": "1",
-"MaxLength": "41",
-"AllowedPattern": "[a-zA-Z0-9]*",
-"ConstraintDescription": "must contain only alphanumeric characters."
-},
-"DBRootPassword": {
-"Default": "admin",
-"NoEcho": "true",
-"Description": "Root password for MySQL",
-"Type": "String",
-"MinLength": "1",
-"MaxLength": "41",
-"AllowedPattern": "[a-zA-Z0-9]*",
-"ConstraintDescription": "must contain only alphanumeric characters."
-},
-"LinuxDistribution": {
-"Default": "F17",
-"Description": "Distribution of choice",
-"Type": "String",
-"AllowedValues": [
-"F18",
-"F17",
-"U10",
-"RHEL-6.1",
-"RHEL-6.2",
-"RHEL-6.3"
-]
-}
-},
-"Mappings": {
-"AWSInstanceType2Arch": {
-"m1.tiny": {
-"Arch": "32"
-},
-"m1.small": {
-"Arch": "64"
-},
-"m1.medium": {
-"Arch": "64"
-},
-"m1.large": {
-"Arch": "64"
-},
-"m1.xlarge": {
-"Arch": "64"
-}
-},
-"DistroArch2AMI": {
-"F18": {
-"32": "F18-i386-cfntools",
-"64": "F18-x86_64-cfntools"
-},
-"F17": {
-"32": "F17-i386-cfntools",
-"64": "F17-x86_64-cfntools"
-},
-"U10": {
-"32": "U10-i386-cfntools",
-"64": "U10-x86_64-cfntools"
-},
-"RHEL-6.1": {
-"32": "rhel61-i386-cfntools",
-"64": "rhel61-x86_64-cfntools"
-},
-"RHEL-6.2": {
-"32": "rhel62-i386-cfntools",
-"64": "rhel62-x86_64-cfntools"
-},
-"RHEL-6.3": {
-"32": "rhel63-i386-cfntools",
-"64": "rhel63-x86_64-cfntools"
-}
-}
-},
-"Resources": {
-"WikiDatabase": {
-"Type": "AWS::EC2::Instance",
-"Metadata": {
-"AWS::CloudFormation::Init": {
-"config": {
-"packages": {
-"yum": {
-"mysql": [],
-"mysql-server": [],
-"httpd": [],
-"wordpress": []
-}
-},
-"services": {
-"systemd": {
-"mysqld": {
-"enabled": "true",
-"ensureRunning": "true"
-},
-"httpd": {
-"enabled": "true",
-"ensureRunning": "true"
-}
-}
-}
-}
-}
-},
-"Properties": {
-"ImageId": {
-"Fn::FindInMap": [
-"DistroArch2AMI",
-{
-"Ref": "LinuxDistribution"
-},
-{
-"Fn::FindInMap": [
-"AWSInstanceType2Arch",
-{
-"Ref": "InstanceType"
-},
-"Arch"
-]
-}
-]
-},
-"InstanceType": {
-"Ref": "InstanceType"
-},
-"KeyName": {
-"Ref": "KeyName"
-},
-"UserData": {
-"Fn::Base64": {
-"Fn::Join": [
-"",
-[
-"#!/bin/bash -v\n",
-"/opt/aws/bin/cfn-init\n"
-]
-]
-}
-}
-}
-}
-},
-"Outputs": {
-"WebsiteURL": {
-"Value": {
-"Fn::Join": [
-"",
-[
-"http://",
-{
-"Fn::GetAtt": [
-"WikiDatabase",
-"PublicIp"
-]
-},
-"/wordpress"
-]
-]
-},
-"Description": "URL for Wordpress wiki"
-}
-}
-}
-"""
-
-VALIDATE = """
-{
-"Description": "AWS CloudFormation Sample Template.",
-"Parameters": {
-"DBUsername": {
-"Type": "String",
-"Description": "The WordPress database admin account username",
-"Default": "admin",
-"MinLength": "1",
-"AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
-"NoEcho": "true",
-"MaxLength": "16",
-"ConstraintDescription": "must begin with a letter and..."
-},
-"LinuxDistribution": {
-"Default": "F17",
-"Type": "String",
-"Description": "Distribution of choice",
-"AllowedValues": [
-"F18",
-"F17",
-"U10",
-"RHEL-6.1",
-"RHEL-6.2",
-"RHEL-6.3"
-]
-},
-"DBRootPassword": {
-"Type": "String",
-"Description": "Root password for MySQL",
-"Default": "admin",
-"MinLength": "1",
-"AllowedPattern": "[a-zA-Z0-9]*",
-"NoEcho": "true",
-"MaxLength": "41",
-"ConstraintDescription": "must contain only alphanumeric characters."
-},
-"KeyName": {
-"Type": "String",
-"Description": "Name of an EC2 KeyPair to enable SSH access to the instances"
-},
-"DBName": {
-"Type": "String",
-"Description": "The WordPress database name",
-"Default": "wordpress",
-"MinLength": "1",
-"AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
-"MaxLength": "64",
-"ConstraintDescription": "must begin with a letter and..."
-},
-"DBPassword": {
-"Type": "String",
-"Description": "The WordPress database admin account password",
-"Default": "admin",
-"MinLength": "1",
-"AllowedPattern": "[a-zA-Z0-9]*",
-"NoEcho": "true",
-"MaxLength": "41",
-"ConstraintDescription": "must contain only alphanumeric characters."
-},
-"InstanceType": {
-"Default": "m1.small",
-"Type": "String",
-"ConstraintDescription": "must be a valid EC2 instance type.",
-"Description": "WebServer EC2 instance type",
-"AllowedValues": [
-"m1.tiny",
-"m1.small",
-"m1.medium",
-"m1.large",
-"m1.xlarge"
-]
-}
-}
-}
-"""
-
-
-class Template(object):
- def __init__(self, data, validate):
- self.data = data
- self.validate = validate
-
-
-def data(TEST):
- TEST.stacks = TestDataContainer()
- TEST.stack_templates = TestDataContainer()
-
- # Stacks
- stack1 = {
- "description": "No description",
- "links": [{
- "href": "http://192.168.1.70:8004/v1/"
- "051c727ee67040d6a7b7812708485a97/"
- "stacks/stack-1211-38/"
- "05b4f39f-ea96-4d91-910c-e758c078a089",
- "rel": "self"
- }],
- "stack_status_reason": "Stack successfully created",
- "stack_name": "stack-test",
- "creation_time": "2013-04-22T00:11:39Z",
- "updated_time": "2013-04-22T00:11:39Z",
- "stack_status": "CREATE_COMPLETE",
- "id": "05b4f39f-ea96-4d91-910c-e758c078a089"
- }
- stack = Stack(StackManager(None), stack1)
- TEST.stacks.add(stack)
-
- TEST.stack_templates.add(Template(TEMPLATE, VALIDATE))
diff --git a/openstack_dashboard/test/test_data/keystone_data.py b/openstack_dashboard/test/test_data/keystone_data.py
deleted file mode 100644
index e92131b1..00000000
--- a/openstack_dashboard/test/test_data/keystone_data.py
+++ /dev/null
@@ -1,269 +0,0 @@
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from datetime import timedelta
-
-from django.conf import settings
-from django.utils import datetime_safe
-
-from keystoneclient.access import AccessInfo
-from keystoneclient.v2_0 import ec2
-from keystoneclient.v2_0 import roles
-from keystoneclient.v2_0 import tenants
-from keystoneclient.v2_0 import users
-from keystoneclient.v3 import domains
-from keystoneclient.v3 import groups
-
-from openstack_auth.user import Token
-
-from openstack_dashboard.test.test_data.utils import TestDataContainer
-
-
-# Dummy service catalog with all service.
-# All endpoint URLs should point to example.com.
-# Try to keep them as accurate to real data as possible (ports, URIs, etc.)
-SERVICE_CATALOG = [
- {"type": "compute",
- "name": "nova",
- "endpoints_links": [],
- "endpoints": [
- {"region": "RegionOne",
- "adminURL": "http://admin.nova.example.com:8774/v2",
- "internalURL": "http://int.nova.example.com:8774/v2",
- "publicURL": "http://public.nova.example.com:8774/v2"},
- {"region": "RegionTwo",
- "adminURL": "http://admin.nova2.example.com:8774/v2",
- "internalURL": "http://int.nova2.example.com:8774/v2",
- "publicURL": "http://public.nova2.example.com:8774/v2"}]},
- {"type": "volume",
- "name": "nova",
- "endpoints_links": [],
- "endpoints": [
- {"region": "RegionOne",
- "adminURL": "http://admin.nova.example.com:8776/v1",
- "internalURL": "http://int.nova.example.com:8776/v1",
- "publicURL": "http://public.nova.example.com:8776/v1"},
- {"region": "RegionTwo",
- "adminURL": "http://admin.nova.example.com:8776/v1",
- "internalURL": "http://int.nova.example.com:8776/v1",
- "publicURL": "http://public.nova.example.com:8776/v1"}]},
- {"type": "image",
- "name": "glance",
- "endpoints_links": [],
- "endpoints": [
- {"region": "RegionOne",
- "adminURL": "http://admin.glance.example.com:9292/v1",
- "internalURL": "http://int.glance.example.com:9292/v1",
- "publicURL": "http://public.glance.example.com:9292/v1"}]},
- {"type": "identity",
- "name": "keystone",
- "endpoints_links": [],
- "endpoints": [
- {"region": "RegionOne",
- "adminURL": "http://admin.keystone.example.com:35357/v2.0",
- "internalURL": "http://int.keystone.example.com:5000/v2.0",
- "publicURL": "http://public.keystone.example.com:5000/v2.0"}]},
- {"type": "object-store",
- "name": "swift",
- "endpoints_links": [],
- "endpoints": [
- {"region": "RegionOne",
- "adminURL": "http://admin.swift.example.com:8080/",
- "internalURL": "http://int.swift.example.com:8080/",
- "publicURL": "http://public.swift.example.com:8080/"}]},
- {"type": "network",
- "name": "neutron",
- "endpoints_links": [],
- "endpoints": [
- {"region": "RegionOne",
- "adminURL": "http://admin.neutron.example.com:9696/",
- "internalURL": "http://int.neutron.example.com:9696/",
- "publicURL": "http://public.neutron.example.com:9696/"}]},
- {"type": "ec2",
- "name": "EC2 Service",
- "endpoints_links": [],
- "endpoints": [
- {"region": "RegionOne",
- "adminURL": "http://admin.nova.example.com:8773/services/Admin",
- "publicURL": "http://public.nova.example.com:8773/services/Cloud",
- "internalURL": "http://int.nova.example.com:8773/services/Cloud"}]},
- {"type": "orchestration",
- "name": "Heat",
- "endpoints_links": [],
- "endpoints": [
- {"region": "RegionOne",
- "adminURL": "http://admin.heat.example.com:8004/v1",
- "publicURL": "http://public.heat.example.com:8004/v1",
- "internalURL": "http://int.heat.example.com:8004/v1"}]}
-]
-
-
-def data(TEST):
- TEST.service_catalog = SERVICE_CATALOG
- TEST.tokens = TestDataContainer()
- TEST.domains = TestDataContainer()
- TEST.users = TestDataContainer()
- TEST.groups = TestDataContainer()
- TEST.tenants = TestDataContainer()
- TEST.roles = TestDataContainer()
- TEST.ec2 = TestDataContainer()
-
- admin_role_dict = {'id': '1',
- 'name': 'admin'}
- admin_role = roles.Role(roles.RoleManager, admin_role_dict)
- member_role_dict = {'id': "2",
- 'name': settings.OPENSTACK_KEYSTONE_DEFAULT_ROLE}
- member_role = roles.Role(roles.RoleManager, member_role_dict)
- TEST.roles.add(admin_role, member_role)
- TEST.roles.admin = admin_role
- TEST.roles.member = member_role
-
- domain_dict = {'id': "1",
- 'name': 'test_domain',
- 'description': "a test domain.",
- 'enabled': True}
- domain_dict_2 = {'id': "2",
- 'name': 'disabled_domain',
- 'description': "a disabled test domain.",
- 'enabled': False}
- domain = domains.Domain(domains.DomainManager, domain_dict)
- disabled_domain = domains.Domain(domains.DomainManager, domain_dict_2)
- TEST.domains.add(domain, disabled_domain)
- TEST.domain = domain # Your "current" domain
-
- user_dict = {'id': "1",
- 'name': 'test_user',
- 'email': 'test@example.com',
- 'password': 'password',
- 'token': 'test_token',
- 'project_id': '1',
- 'enabled': True,
- 'domain_id': "1"}
- user = users.User(users.UserManager(None), user_dict)
- user_dict = {'id': "2",
- 'name': 'user_two',
- 'email': 'two@example.com',
- 'password': 'password',
- 'token': 'test_token',
- 'project_id': '1',
- 'enabled': True,
- 'domain_id': "1"}
- user2 = users.User(users.UserManager(None), user_dict)
- user_dict = {'id': "3",
- 'name': 'user_three',
- 'email': 'three@example.com',
- 'password': 'password',
- 'token': 'test_token',
- 'project_id': '1',
- 'enabled': True,
- 'domain_id': "1"}
- user3 = users.User(users.UserManager(None), user_dict)
- user_dict = {'id': "4",
- 'name': 'user_four',
- 'email': 'four@example.com',
- 'password': 'password',
- 'token': 'test_token',
- 'project_id': '2',
- 'enabled': True,
- 'domain_id': "2"}
- user4 = users.User(users.UserManager(None), user_dict)
- TEST.users.add(user, user2, user3, user4)
- TEST.user = user # Your "current" user
- TEST.user.service_catalog = SERVICE_CATALOG
-
- group_dict = {'id': "1",
- 'name': 'group_one',
- 'description': 'group one description',
- 'domain_id': '1'}
- group = groups.Group(groups.GroupManager(None), group_dict)
- group_dict = {'id': "2",
- 'name': 'group_two',
- 'description': 'group two description',
- 'domain_id': '1'}
- group2 = groups.Group(groups.GroupManager(None), group_dict)
- group_dict = {'id': "3",
- 'name': 'group_three',
- 'description': 'group three description',
- 'domain_id': '2'}
- group3 = groups.Group(groups.GroupManager(None), group_dict)
- TEST.groups.add(group, group2, group3)
-
- tenant_dict = {'id': "1",
- 'name': 'test_tenant',
- 'description': "a test tenant.",
- 'enabled': True,
- 'domain_id': '1'}
- tenant_dict_2 = {'id': "2",
- 'name': 'disabled_tenant',
- 'description': "a disabled test tenant.",
- 'enabled': False,
- 'domain_id': '2'}
- tenant_dict_3 = {'id': "3",
- 'name': u'\u4e91\u89c4\u5219',
- 'description': "an unicode-named tenant.",
- 'enabled': True,
- 'domain_id': '2'}
- tenant = tenants.Tenant(tenants.TenantManager, tenant_dict)
- disabled_tenant = tenants.Tenant(tenants.TenantManager, tenant_dict_2)
- tenant_unicode = tenants.Tenant(tenants.TenantManager, tenant_dict_3)
-
- TEST.tenants.add(tenant, disabled_tenant, tenant_unicode)
- TEST.tenant = tenant # Your "current" tenant
-
- tomorrow = datetime_safe.datetime.now() + timedelta(days=1)
- expiration = datetime_safe.datetime.isoformat(tomorrow)
-
- scoped_token_dict = {
- 'access': {
- 'token': {
- 'id': "test_token_id",
- 'expires': expiration,
- 'tenant': tenant_dict,
- 'tenants': [tenant_dict]},
- 'user': {
- 'id': "test_user_id",
- 'name': "test_user",
- 'roles': [member_role_dict]},
- 'serviceCatalog': TEST.service_catalog
- }
- }
-
- scoped_access_info = AccessInfo.factory(resp=None,
- body=scoped_token_dict)
-
- unscoped_token_dict = {
- 'access': {
- 'token': {
- 'id': "test_token_id",
- 'expires': expiration},
- 'user': {
- 'id': "test_user_id",
- 'name': "test_user",
- 'roles': [member_role_dict]},
- 'serviceCatalog': TEST.service_catalog
- }
- }
- unscoped_access_info = AccessInfo.factory(resp=None,
- body=unscoped_token_dict)
-
- scoped_token = Token(scoped_access_info)
- unscoped_token = Token(unscoped_access_info)
- TEST.tokens.add(scoped_token, unscoped_token)
- TEST.token = scoped_token # your "current" token.
- TEST.tokens.scoped_token = scoped_token
- TEST.tokens.unscoped_token = unscoped_token
-
- access_secret = ec2.EC2(ec2.CredentialsManager, {"access": "access",
- "secret": "secret"})
- TEST.ec2.add(access_secret)
diff --git a/openstack_dashboard/test/test_data/neutron_data.py b/openstack_dashboard/test/test_data/neutron_data.py
deleted file mode 100644
index cabf6b3f..00000000
--- a/openstack_dashboard/test/test_data/neutron_data.py
+++ /dev/null
@@ -1,458 +0,0 @@
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import copy
-import uuid
-
-from openstack_dashboard.api.lbaas import Member
-from openstack_dashboard.api.lbaas import Pool
-from openstack_dashboard.api.lbaas import PoolMonitor
-from openstack_dashboard.api.lbaas import Vip
-
-from openstack_dashboard.api.neutron import FloatingIp
-from openstack_dashboard.api.neutron import Network
-from openstack_dashboard.api.neutron import Port
-from openstack_dashboard.api.neutron import Router
-from openstack_dashboard.api.neutron import SecurityGroup
-from openstack_dashboard.api.neutron import SecurityGroupRule
-from openstack_dashboard.api.neutron import Subnet
-
-from openstack_dashboard.test.test_data.utils import TestDataContainer
-
-
-def data(TEST):
- # data returned by openstack_dashboard.api.neutron wrapper
- TEST.networks = TestDataContainer()
- TEST.subnets = TestDataContainer()
- TEST.ports = TestDataContainer()
- TEST.routers = TestDataContainer()
- TEST.q_floating_ips = TestDataContainer()
- TEST.q_secgroups = TestDataContainer()
- TEST.q_secgroup_rules = TestDataContainer()
- TEST.pools = TestDataContainer()
- TEST.vips = TestDataContainer()
- TEST.members = TestDataContainer()
- TEST.monitors = TestDataContainer()
-
- # data return by neutronclient
- TEST.api_networks = TestDataContainer()
- TEST.api_subnets = TestDataContainer()
- TEST.api_ports = TestDataContainer()
- TEST.api_routers = TestDataContainer()
- TEST.api_q_floating_ips = TestDataContainer()
- TEST.api_q_secgroups = TestDataContainer()
- TEST.api_q_secgroup_rules = TestDataContainer()
- TEST.api_pools = TestDataContainer()
- TEST.api_vips = TestDataContainer()
- TEST.api_members = TestDataContainer()
- TEST.api_monitors = TestDataContainer()
-
- #------------------------------------------------------------
- # 1st network
- network_dict = {'admin_state_up': True,
- 'id': '82288d84-e0a5-42ac-95be-e6af08727e42',
- 'name': 'net1',
- 'status': 'ACTIVE',
- 'subnets': ['e8abc972-eb0c-41f1-9edd-4bc6e3bcd8c9'],
- 'tenant_id': '1',
- 'router:external': False,
- 'shared': False}
- subnet_dict = {'allocation_pools': [{'end': '10.0.0.254',
- 'start': '10.0.0.2'}],
- 'dns_nameservers': [],
- 'host_routes': [],
- 'cidr': '10.0.0.0/24',
- 'enable_dhcp': True,
- 'gateway_ip': '10.0.0.1',
- 'id': network_dict['subnets'][0],
- 'ip_version': 4,
- 'name': 'mysubnet1',
- 'network_id': network_dict['id'],
- 'tenant_id': network_dict['tenant_id']}
-
- TEST.api_networks.add(network_dict)
- TEST.api_subnets.add(subnet_dict)
-
- network = copy.deepcopy(network_dict)
- subnet = Subnet(subnet_dict)
- network['subnets'] = [subnet]
- TEST.networks.add(Network(network))
- TEST.subnets.add(subnet)
-
- # ports on 1st network
- port_dict = {'admin_state_up': True,
- 'device_id': 'af75c8e5-a1cc-4567-8d04-44fcd6922890',
- 'device_owner': 'network:dhcp',
- 'fixed_ips': [{'ip_address': '10.0.0.3',
- 'subnet_id': subnet_dict['id']}],
- 'id': '063cf7f3-ded1-4297-bc4c-31eae876cc91',
- 'mac_address': 'fa:16:3e:9c:d5:7e',
- 'name': '',
- 'network_id': network_dict['id'],
- 'status': 'ACTIVE',
- 'tenant_id': network_dict['tenant_id']}
- TEST.api_ports.add(port_dict)
- TEST.ports.add(Port(port_dict))
-
- port_dict = {'admin_state_up': True,
- 'device_id': '1',
- 'device_owner': 'compute:nova',
- 'fixed_ips': [{'ip_address': '10.0.0.4',
- 'subnet_id': subnet_dict['id']}],
- 'id': '7e6ce62c-7ea2-44f8-b6b4-769af90a8406',
- 'mac_address': 'fa:16:3e:9d:e6:2f',
- 'name': '',
- 'network_id': network_dict['id'],
- 'status': 'ACTIVE',
- 'tenant_id': network_dict['tenant_id']}
- TEST.api_ports.add(port_dict)
- TEST.ports.add(Port(port_dict))
- assoc_port = port_dict
-
- #------------------------------------------------------------
- # 2nd network
- network_dict = {'admin_state_up': True,
- 'id': '72c3ab6c-c80f-4341-9dc5-210fa31ac6c2',
- 'name': 'net2',
- 'status': 'ACTIVE',
- 'subnets': ['3f7c5d79-ee55-47b0-9213-8e669fb03009'],
- 'tenant_id': '2',
- 'router:external': False,
- 'shared': True}
- subnet_dict = {'allocation_pools': [{'end': '172.16.88.254',
- 'start': '172.16.88.2'}],
- 'dns_nameservers': ['10.56.1.20', '10.56.1.21'],
- 'host_routes': [{'destination': '192.168.20.0/24',
- 'nexthop': '172.16.88.253'},
- {'destination': '192.168.21.0/24',
- 'nexthop': '172.16.88.252'}],
- 'cidr': '172.16.88.0/24',
- 'enable_dhcp': True,
- 'gateway_ip': '172.16.88.1',
- 'id': '3f7c5d79-ee55-47b0-9213-8e669fb03009',
- 'ip_version': 4,
- 'name': 'aaaa',
- 'network_id': network_dict['id'],
- 'tenant_id': network_dict['tenant_id']}
-
- TEST.api_networks.add(network_dict)
- TEST.api_subnets.add(subnet_dict)
-
- network = copy.deepcopy(network_dict)
- subnet = Subnet(subnet_dict)
- network['subnets'] = [subnet]
- TEST.networks.add(Network(network))
- TEST.subnets.add(subnet)
-
- port_dict = {'admin_state_up': True,
- 'device_id': '2',
- 'device_owner': 'compute:nova',
- 'fixed_ips': [{'ip_address': '172.16.88.3',
- 'subnet_id': subnet_dict['id']}],
- 'id': '1db2cc37-3553-43fa-b7e2-3fc4eb4f9905',
- 'mac_address': 'fa:16:3e:56:e6:2f',
- 'name': '',
- 'network_id': network_dict['id'],
- 'status': 'ACTIVE',
- 'tenant_id': network_dict['tenant_id']}
-
- TEST.api_ports.add(port_dict)
- TEST.ports.add(Port(port_dict))
-
- #------------------------------------------------------------
- # external network
- network_dict = {'admin_state_up': True,
- 'id': '9b466b94-213a-4cda-badf-72c102a874da',
- 'name': 'ext_net',
- 'status': 'ACTIVE',
- 'subnets': ['d6bdc71c-7566-4d32-b3ff-36441ce746e8'],
- 'tenant_id': '3',
- 'router:external': True,
- 'shared': False}
- subnet_dict = {'allocation_pools': [{'start': '172.24.4.226.',
- 'end': '172.24.4.238'}],
- 'dns_nameservers': [],
- 'host_routes': [],
- 'cidr': '172.24.4.0/28',
- 'enable_dhcp': False,
- 'gateway_ip': '172.24.4.225',
- 'id': 'd6bdc71c-7566-4d32-b3ff-36441ce746e8',
- 'ip_version': 4,
- 'name': 'ext_subnet',
- 'network_id': network_dict['id'],
- 'tenant_id': network_dict['tenant_id']}
- ext_net = network_dict
-
- TEST.api_networks.add(network_dict)
- TEST.api_subnets.add(subnet_dict)
-
- network = copy.deepcopy(network_dict)
- subnet = Subnet(subnet_dict)
- network['subnets'] = [subnet]
- TEST.networks.add(Network(network))
- TEST.subnets.add(subnet)
-
- #------------------------------------------------------------
- # Set up router data
- port_dict = {'admin_state_up': True,
- 'device_id': '7180cede-bcd8-4334-b19f-f7ef2f331f53',
- 'device_owner': 'network:router_gateway',
- 'fixed_ips': [{'ip_address': '10.0.0.3',
- 'subnet_id': subnet_dict['id']}],
- 'id': '44ec6726-4bdc-48c5-94d4-df8d1fbf613b',
- 'mac_address': 'fa:16:3e:9c:d5:7e',
- 'name': '',
- 'network_id': network_dict['id'],
- 'status': 'ACTIVE',
- 'tenant_id': '1'}
- TEST.api_ports.add(port_dict)
- TEST.ports.add(Port(port_dict))
-
- router_dict = {'id': '279989f7-54bb-41d9-ba42-0d61f12fda61',
- 'name': 'router1',
- 'external_gateway_info':
- {'network_id': ext_net['id']},
- 'tenant_id': '1'}
- TEST.api_routers.add(router_dict)
- TEST.routers.add(Router(router_dict))
- router_dict = {'id': '10e3dc42-1ce1-4d48-87cf-7fc333055d6c',
- 'name': 'router2',
- 'external_gateway_info':
- {'network_id': ext_net['id']},
- 'tenant_id': '1'}
- TEST.api_routers.add(router_dict)
- TEST.routers.add(Router(router_dict))
-
- #------------------------------------------------------------
- # floating IP
- # unassociated
- fip_dict = {'tenant_id': '1',
- 'floating_ip_address': '172.16.88.227',
- 'floating_network_id': ext_net['id'],
- 'id': '9012cd70-cfae-4e46-b71e-6a409e9e0063',
- 'fixed_ip_address': None,
- 'port_id': None,
- 'router_id': None}
- TEST.api_q_floating_ips.add(fip_dict)
- TEST.q_floating_ips.add(FloatingIp(fip_dict))
-
- # associated (with compute port on 1st network)
- fip_dict = {'tenant_id': '1',
- 'floating_ip_address': '172.16.88.228',
- 'floating_network_id': ext_net['id'],
- 'id': 'a97af8f2-3149-4b97-abbd-e49ad19510f7',
- 'fixed_ip_address': assoc_port['fixed_ips'][0]['ip_address'],
- 'port_id': assoc_port['id'],
- 'router_id': router_dict['id']}
- TEST.api_q_floating_ips.add(fip_dict)
- TEST.q_floating_ips.add(FloatingIp(fip_dict))
-
- #------------------------------------------------------------
- # security group
-
- sec_group_1 = {'tenant_id': '1',
- 'description': 'default',
- 'id': 'faad7c80-3b62-4440-967c-13808c37131d',
- 'name': 'default'}
- sec_group_2 = {'tenant_id': '1',
- 'description': 'NotDefault',
- 'id': '27a5c9a1-bdbb-48ac-833a-2e4b5f54b31d',
- 'name': 'other_group'}
- sec_group_3 = {'tenant_id': '1',
- 'description': 'NotDefault',
- 'id': '443a4d7a-4bd2-4474-9a77-02b35c9f8c95',
- 'name': 'another_group'}
-
- def add_rule_to_group(secgroup, default_only=True):
- rule_egress_ipv4 = {
- 'id': str(uuid.uuid4()),
- 'direction': u'egress', 'ethertype': u'IPv4',
- 'port_range_min': None, 'port_range_max': None,
- 'protocol': None, 'remote_group_id': None,
- 'remote_ip_prefix': None,
- 'security_group_id': secgroup['id'],
- 'tenant_id': secgroup['tenant_id']}
- rule_egress_ipv6 = {
- 'id': str(uuid.uuid4()),
- 'direction': u'egress', 'ethertype': u'IPv6',
- 'port_range_min': None, 'port_range_max': None,
- 'protocol': None, 'remote_group_id': None,
- 'remote_ip_prefix': None,
- 'security_group_id': secgroup['id'],
- 'tenant_id': secgroup['tenant_id']}
-
- rule_tcp_80 = {
- 'id': str(uuid.uuid4()),
- 'direction': u'ingress', 'ethertype': u'IPv4',
- 'port_range_min': 80, 'port_range_max': 80,
- 'protocol': u'tcp', 'remote_group_id': None,
- 'remote_ip_prefix': u'0.0.0.0/0',
- 'security_group_id': secgroup['id'],
- 'tenant_id': secgroup['tenant_id']}
- rule_icmp = {
- 'id': str(uuid.uuid4()),
- 'direction': u'ingress', 'ethertype': u'IPv4',
- 'port_range_min': 5, 'port_range_max': 8,
- 'protocol': u'icmp', 'remote_group_id': None,
- 'remote_ip_prefix': u'0.0.0.0/0',
- 'security_group_id': secgroup['id'],
- 'tenant_id': secgroup['tenant_id']}
- rule_group = {
- 'id': str(uuid.uuid4()),
- 'direction': u'ingress', 'ethertype': u'IPv4',
- 'port_range_min': 80, 'port_range_max': 80,
- 'protocol': u'tcp', 'remote_group_id': sec_group_1['id'],
- 'remote_ip_prefix': None,
- 'security_group_id': secgroup['id'],
- 'tenant_id': secgroup['tenant_id']}
-
- rules = []
- if not default_only:
- rules += [rule_tcp_80, rule_icmp, rule_group]
- rules += [rule_egress_ipv4, rule_egress_ipv6]
- secgroup['security_group_rules'] = rules
-
- add_rule_to_group(sec_group_1, default_only=False)
- add_rule_to_group(sec_group_2)
- add_rule_to_group(sec_group_3)
-
- groups = [sec_group_1, sec_group_2, sec_group_3]
- sg_name_dict = dict([(sg['id'], sg['name']) for sg in groups])
- for sg in groups:
- # Neutron API
- TEST.api_q_secgroups.add(sg)
- for rule in sg['security_group_rules']:
- TEST.api_q_secgroup_rules.add(copy.copy(rule))
- # OpenStack Dashboard internaly API
- TEST.q_secgroups.add(SecurityGroup(copy.deepcopy(sg), sg_name_dict))
- for rule in sg['security_group_rules']:
- TEST.q_secgroup_rules.add(
- SecurityGroupRule(copy.copy(rule), sg_name_dict))
-
- #------------------------------------------------------------
- # LBaaS
-
- # 1st pool
- pool_dict = {'id': '8913dde8-4915-4b90-8d3e-b95eeedb0d49',
- 'tenant_id': '1',
- 'vip_id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'name': 'pool1',
- 'description': 'pool description',
- 'subnet_id': TEST.subnets.first().id,
- 'protocol': 'HTTP',
- 'lb_method': 'ROUND_ROBIN',
- 'health_monitors': ['d4a0500f-db2b-4cc4-afcf-ec026febff96'],
- 'admin_state_up': True}
- TEST.api_pools.add(pool_dict)
- TEST.pools.add(Pool(pool_dict))
-
- # 1st vip
- vip_dict = {'id': 'abcdef-c3eb-4fee-9763-12de3338041e',
- 'name': 'vip1',
- 'address': '10.0.0.100',
- 'floatip_address': '',
- 'other_address': '10.0.0.100',
- 'description': 'vip description',
- 'subnet_id': TEST.subnets.first().id,
- 'subnet': TEST.subnets.first().cidr,
- 'protocol_port': 80,
- 'protocol': pool_dict['protocol'],
- 'pool_id': pool_dict['id'],
- 'session_persistence': {'type': 'APP_COOKIE',
- 'cookie_name': 'jssessionid'},
- 'connection_limit': 10,
- 'admin_state_up': True}
- TEST.api_vips.add(vip_dict)
- TEST.vips.add(Vip(vip_dict))
-
- # 2nd vip
- vip_dict = {'id': 'f0881d38-c3eb-4fee-9763-12de3338041d',
- 'name': 'vip2',
- 'address': '10.0.0.110',
- 'floatip_address': '',
- 'other_address': '10.0.0.110',
- 'description': 'vip description',
- 'subnet_id': TEST.subnets.first().id,
- 'subnet': TEST.subnets.first().cidr,
- 'protocol_port': 80,
- 'protocol': pool_dict['protocol'],
- 'pool_id': pool_dict['id'],
- 'session_persistence': {'type': 'APP_COOKIE',
- 'cookie_name': 'jssessionid'},
- 'connection_limit': 10,
- 'admin_state_up': True}
- TEST.api_vips.add(vip_dict)
- TEST.vips.add(Vip(vip_dict))
-
- # 1st member
- member_dict = {'id': '78a46e5e-eb1a-418a-88c7-0e3f5968b08',
- 'tenant_id': '1',
- 'pool_id': pool_dict['id'],
- 'address': '10.0.0.11',
- 'protocol_port': 80,
- 'weight': 10,
- 'admin_state_up': True}
- TEST.api_members.add(member_dict)
- TEST.members.add(Member(member_dict))
-
- # 2nd member
- member_dict = {'id': '41ac1f8d-6d9c-49a4-a1bf-41955e651f91',
- 'tenant_id': '1',
- 'pool_id': pool_dict['id'],
- 'address': '10.0.0.12',
- 'protocol_port': 80,
- 'weight': 10,
- 'admin_state_up': True}
- TEST.api_members.add(member_dict)
- TEST.members.add(Member(member_dict))
-
- # 2nd pool
- pool_dict = {'id': '8913dde8-4915-4b90-8d3e-b95eeedb0d50',
- 'tenant_id': '1',
- 'vip_id': 'f0881d38-c3eb-4fee-9763-12de3338041d',
- 'name': 'pool2',
- 'description': 'pool description',
- 'subnet_id': TEST.subnets.first().id,
- 'protocol': 'HTTPS',
- 'lb_method': 'ROUND_ROBIN',
- 'health_monitors': ['d4a0500f-db2b-4cc4-afcf-ec026febff97'],
- 'admin_state_up': True}
- TEST.api_pools.add(pool_dict)
- TEST.pools.add(Pool(pool_dict))
-
- # 1st monitor
- monitor_dict = {'id': 'd4a0500f-db2b-4cc4-afcf-ec026febff96',
- 'type': 'ping',
- 'delay': 10,
- 'timeout': 10,
- 'max_retries': 10,
- 'http_method': 'GET',
- 'url_path': '/',
- 'expected_codes': '200',
- 'admin_state_up': True}
- TEST.api_monitors.add(monitor_dict)
- TEST.monitors.add(PoolMonitor(monitor_dict))
-
- # 2nd monitor
- monitor_dict = {'id': 'd4a0500f-db2b-4cc4-afcf-ec026febff97',
- 'type': 'ping',
- 'delay': 10,
- 'timeout': 10,
- 'max_retries': 10,
- 'http_method': 'GET',
- 'url_path': '/',
- 'expected_codes': '200',
- 'admin_state_up': True}
- TEST.api_monitors.add(monitor_dict)
- TEST.monitors.add(PoolMonitor(monitor_dict))
diff --git a/openstack_dashboard/test/test_data/nova_data.py b/openstack_dashboard/test/test_data/nova_data.py
deleted file mode 100644
index 326683d8..00000000
--- a/openstack_dashboard/test/test_data/nova_data.py
+++ /dev/null
@@ -1,583 +0,0 @@
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import json
-import uuid
-
-from novaclient.v1_1 import aggregates
-from novaclient.v1_1 import availability_zones
-from novaclient.v1_1 import certs
-from novaclient.v1_1 import flavors
-from novaclient.v1_1 import floating_ips
-from novaclient.v1_1 import hypervisors
-from novaclient.v1_1 import keypairs
-from novaclient.v1_1 import quotas
-from novaclient.v1_1 import security_group_rules as rules
-from novaclient.v1_1 import security_groups as sec_groups
-from novaclient.v1_1 import servers
-from novaclient.v1_1 import services
-from novaclient.v1_1 import usage
-from novaclient.v1_1 import volume_snapshots as vol_snaps
-from novaclient.v1_1 import volume_types
-from novaclient.v1_1 import volumes
-
-from openstack_dashboard.api.base import Quota
-from openstack_dashboard.api.base import QuotaSet as QuotaSetWrapper
-from openstack_dashboard.api.nova import FloatingIp as NetFloatingIp
-from openstack_dashboard.usage.quotas import QuotaUsage
-
-from openstack_dashboard.test.test_data.utils import TestDataContainer
-
-
-SERVER_DATA = """
-{
- "server": {
- "OS-EXT-SRV-ATTR:instance_name": "instance-00000005",
- "OS-EXT-SRV-ATTR:host": "instance-host",
- "OS-EXT-STS:task_state": null,
- "addresses": {
- "private": [
- {
- "version": 4,
- "addr": "10.0.0.1"
- }
- ]
- },
- "links": [
- {
- "href": "%(host)s/v1.1/%(tenant_id)s/servers/%(server_id)s",
- "rel": "self"
- },
- {
- "href": "%(host)s/%(tenant_id)s/servers/%(server_id)s",
- "rel": "bookmark"
- }
- ],
- "image": {
- "id": "%(image_id)s",
- "links": [
- {
- "href": "%(host)s/%(tenant_id)s/images/%(image_id)s",
- "rel": "bookmark"
- }
- ]
- },
- "OS-EXT-STS:vm_state": "active",
- "flavor": {
- "id": "%(flavor_id)s",
- "links": [
- {
- "href": "%(host)s/%(tenant_id)s/flavors/%(flavor_id)s",
- "rel": "bookmark"
- }
- ]
- },
- "id": "%(server_id)s",
- "user_id": "%(user_id)s",
- "OS-DCF:diskConfig": "MANUAL",
- "accessIPv4": "",
- "accessIPv6": "",
- "progress": null,
- "OS-EXT-STS:power_state": 1,
- "config_drive": "",
- "status": "%(status)s",
- "updated": "2012-02-28T19:51:27Z",
- "hostId": "c461ea283faa0ab5d777073c93b126c68139e4e45934d4fc37e403c2",
- "key_name": "%(key_name)s",
- "name": "%(name)s",
- "created": "2012-02-28T19:51:17Z",
- "tenant_id": "%(tenant_id)s",
- "metadata": {"someMetaLabel": "someMetaData",
- "some<b>html</b>label": "<!--",
- "empty": ""}
- }
-}
-"""
-
-
-USAGE_DATA = """
-{
- "total_memory_mb_usage": 64246.89777777778,
- "total_vcpus_usage": 125.48222222222223,
- "total_hours": 125.48222222222223,
- "total_local_gb_usage": 0,
- "tenant_id": "%(tenant_id)s",
- "stop": "2012-01-31 23:59:59",
- "start": "2012-01-01 00:00:00",
- "server_usages": [
- {
- "memory_mb": %(flavor_ram)s,
- "uptime": 442321,
- "started_at": "2012-01-26 20:38:21",
- "ended_at": null,
- "name": "%(instance_name)s",
- "tenant_id": "%(tenant_id)s",
- "state": "active",
- "hours": 122.87361111111112,
- "vcpus": %(flavor_vcpus)s,
- "flavor": "%(flavor_name)s",
- "local_gb": %(flavor_disk)s
- },
- {
- "memory_mb": %(flavor_ram)s,
- "uptime": 9367,
- "started_at": "2012-01-31 20:54:15",
- "ended_at": null,
- "name": "%(instance_name)s",
- "tenant_id": "%(tenant_id)s",
- "state": "active",
- "hours": 2.608611111111111,
- "vcpus": %(flavor_vcpus)s,
- "flavor": "%(flavor_name)s",
- "local_gb": %(flavor_disk)s
- }
- ]
-}
-"""
-
-
-def data(TEST):
- TEST.servers = TestDataContainer()
- TEST.flavors = TestDataContainer()
- TEST.keypairs = TestDataContainer()
- TEST.security_groups = TestDataContainer()
- TEST.security_groups_uuid = TestDataContainer()
- TEST.security_group_rules = TestDataContainer()
- TEST.security_group_rules_uuid = TestDataContainer()
- TEST.volumes = TestDataContainer()
- TEST.quotas = TestDataContainer()
- TEST.quota_usages = TestDataContainer()
- TEST.floating_ips = TestDataContainer()
- TEST.floating_ips_uuid = TestDataContainer()
- TEST.usages = TestDataContainer()
- TEST.certs = TestDataContainer()
- TEST.volume_snapshots = TestDataContainer()
- TEST.volume_types = TestDataContainer()
- TEST.availability_zones = TestDataContainer()
- TEST.hypervisors = TestDataContainer()
- TEST.services = TestDataContainer()
- TEST.aggregates = TestDataContainer()
-
- # Data return by novaclient.
- # It is used if API layer does data conversion.
- TEST.api_floating_ips = TestDataContainer()
- TEST.api_floating_ips_uuid = TestDataContainer()
-
- # Volumes
- volume = volumes.Volume(volumes.VolumeManager(None),
- dict(id="41023e92-8008-4c8b-8059-7f2293ff3775",
- name='test_volume',
- status='available',
- size=40,
- display_name='Volume name',
- created_at='2012-04-01 10:30:00',
- volume_type=None,
- attachments=[]))
- nameless_volume = volumes.Volume(volumes.VolumeManager(None),
- dict(id="3b189ac8-9166-ac7f-90c9-16c8bf9e01ac",
- name='',
- status='in-use',
- size=10,
- display_name='',
- display_description='',
- device="/dev/hda",
- created_at='2010-11-21 18:34:25',
- volume_type='vol_type_1',
- attachments=[{"id": "1", "server_id": '1',
- "device": "/dev/hda"}]))
- attached_volume = volumes.Volume(volumes.VolumeManager(None),
- dict(id="8cba67c1-2741-6c79-5ab6-9c2bf8c96ab0",
- name='my_volume',
- status='in-use',
- size=30,
- display_name='My Volume',
- display_description='',
- device="/dev/hdk",
- created_at='2011-05-01 11:54:33',
- volume_type='vol_type_2',
- attachments=[{"id": "2", "server_id": '1',
- "device": "/dev/hdk"}]))
- TEST.volumes.add(volume)
- TEST.volumes.add(nameless_volume)
- TEST.volumes.add(attached_volume)
-
- vol_type1 = volume_types.VolumeType(volume_types.VolumeTypeManager(None),
- {'id': 1,
- 'name': 'vol_type_1'})
- vol_type2 = volume_types.VolumeType(volume_types.VolumeTypeManager(None),
- {'id': 2,
- 'name': 'vol_type_2'})
- TEST.volume_types.add(vol_type1, vol_type2)
-
- # Flavors
- flavor_1 = flavors.Flavor(flavors.FlavorManager(None),
- {'id': "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
- 'name': 'm1.tiny',
- 'vcpus': 1,
- 'disk': 0,
- 'ram': 512,
- 'swap': 0,
- 'extra_specs': {},
- 'OS-FLV-EXT-DATA:ephemeral': 0})
- flavor_2 = flavors.Flavor(flavors.FlavorManager(None),
- {'id': "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb",
- 'name': 'm1.massive',
- 'vcpus': 1000,
- 'disk': 1024,
- 'ram': 10000,
- 'swap': 0,
- 'extra_specs': {'Trusted': True, 'foo': 'bar'},
- 'OS-FLV-EXT-DATA:ephemeral': 2048})
- TEST.flavors.add(flavor_1, flavor_2)
-
- # Keypairs
- keypair = keypairs.Keypair(keypairs.KeypairManager(None),
- dict(name='keyName'))
- TEST.keypairs.add(keypair)
-
- # Security Groups and Rules
- def generate_security_groups(is_uuid=False):
-
- def get_id(is_uuid):
- global current_int_id
- if is_uuid:
- return str(uuid.uuid4())
- else:
- get_id.current_int_id += 1
- return get_id.current_int_id
-
- get_id.current_int_id = 0
-
- sg_manager = sec_groups.SecurityGroupManager(None)
- rule_manager = rules.SecurityGroupRuleManager(None)
-
- sec_group_1 = sec_groups.SecurityGroup(sg_manager,
- {"rules": [],
- "tenant_id": TEST.tenant.id,
- "id": get_id(is_uuid),
- "name": u"default",
- "description": u"default"})
- sec_group_2 = sec_groups.SecurityGroup(sg_manager,
- {"rules": [],
- "tenant_id": TEST.tenant.id,
- "id": get_id(is_uuid),
- "name": u"other_group",
- "description": u"NotDefault."})
- sec_group_3 = sec_groups.SecurityGroup(sg_manager,
- {"rules": [],
- "tenant_id": TEST.tenant.id,
- "id": get_id(is_uuid),
- "name": u"another_group",
- "description": u"NotDefault."})
-
- rule = {'id': get_id(is_uuid),
- 'group': {},
- 'ip_protocol': u"tcp",
- 'from_port': u"80",
- 'to_port': u"80",
- 'parent_group_id': sec_group_1.id,
- 'ip_range': {'cidr': u"0.0.0.0/32"}}
-
- icmp_rule = {'id': get_id(is_uuid),
- 'group': {},
- 'ip_protocol': u"icmp",
- 'from_port': u"9",
- 'to_port': u"5",
- 'parent_group_id': sec_group_1.id,
- 'ip_range': {'cidr': u"0.0.0.0/32"}}
-
- group_rule = {'id': 3,
- 'group': {},
- 'ip_protocol': u"tcp",
- 'from_port': u"80",
- 'to_port': u"80",
- 'parent_group_id': sec_group_1.id,
- 'source_group_id': sec_group_1.id}
-
- rule_obj = rules.SecurityGroupRule(rule_manager, rule)
- rule_obj2 = rules.SecurityGroupRule(rule_manager, icmp_rule)
- rule_obj3 = rules.SecurityGroupRule(rule_manager, group_rule)
-
- sec_group_1.rules = [rule_obj]
- sec_group_2.rules = [rule_obj]
-
- return {"rules": [rule_obj, rule_obj2, rule_obj3],
- "groups": [sec_group_1, sec_group_2, sec_group_3]}
-
- sg_data = generate_security_groups()
- TEST.security_group_rules.add(*sg_data["rules"])
- TEST.security_groups.add(*sg_data["groups"])
-
- sg_uuid_data = generate_security_groups(is_uuid=True)
- TEST.security_group_rules_uuid.add(*sg_uuid_data["rules"])
- TEST.security_groups_uuid.add(*sg_uuid_data["groups"])
-
- # Quota Sets
- quota_data = dict(metadata_items='1',
- injected_file_content_bytes='1',
- volumes='1',
- gigabytes='1000',
- ram=10000,
- floating_ips='1',
- fixed_ips='10',
- instances='10',
- injected_files='1',
- cores='10',
- security_groups='10',
- security_group_rules='20')
- quota = quotas.QuotaSet(quotas.QuotaSetManager(None), quota_data)
- TEST.quotas.nova = QuotaSetWrapper(quota)
- TEST.quotas.add(QuotaSetWrapper(quota))
-
- # Quota Usages
- quota_usage_data = {'gigabytes': {'used': 0,
- 'quota': 1000},
- 'instances': {'used': 0,
- 'quota': 10},
- 'ram': {'used': 0,
- 'quota': 10000},
- 'cores': {'used': 0,
- 'quota': 20}}
- quota_usage = QuotaUsage()
- for k, v in quota_usage_data.items():
- quota_usage.add_quota(Quota(k, v['quota']))
- quota_usage.tally(k, v['used'])
-
- TEST.quota_usages.add(quota_usage)
-
- # Limits
- limits = {"absolute": {"maxImageMeta": 128,
- "maxPersonality": 5,
- "maxPersonalitySize": 10240,
- "maxSecurityGroupRules": 20,
- "maxSecurityGroups": 10,
- "maxServerMeta": 128,
- "maxTotalCores": 20,
- "maxTotalFloatingIps": 10,
- "maxTotalInstances": 10,
- "maxTotalKeypairs": 100,
- "maxTotalRAMSize": 10000,
- "totalCoresUsed": 0,
- "totalInstancesUsed": 0,
- "totalKeyPairsUsed": 0,
- "totalRAMUsed": 0,
- "totalSecurityGroupsUsed": 0}}
- TEST.limits = limits
-
- # Servers
- tenant3 = TEST.tenants.list()[2]
-
- vals = {"host": "http://nova.example.com:8774",
- "name": "server_1",
- "status": "ACTIVE",
- "tenant_id": TEST.tenants.first().id,
- "user_id": TEST.user.id,
- "server_id": "1",
- "flavor_id": flavor_1.id,
- "image_id": TEST.images.first().id,
- "key_name": keypair.name}
- server_1 = servers.Server(servers.ServerManager(None),
- json.loads(SERVER_DATA % vals)['server'])
- vals.update({"name": "server_2",
- "status": "BUILD",
- "server_id": "2"})
- server_2 = servers.Server(servers.ServerManager(None),
- json.loads(SERVER_DATA % vals)['server'])
- vals.update({"name": u'\u4e91\u89c4\u5219',
- "status": "ACTIVE",
- "tenant_id": tenant3.id,
- "server_id": "3"})
- server_3 = servers.Server(servers.ServerManager(None),
- json.loads(SERVER_DATA % vals)['server'])
- TEST.servers.add(server_1, server_2, server_3)
-
- # VNC Console Data
- console = {u'console': {u'url': u'http://example.com:6080/vnc_auto.html',
- u'type': u'novnc'}}
- TEST.servers.vnc_console_data = console
- # SPICE Console Data
- console = {u'console': {u'url': u'http://example.com:6080/spice_auto.html',
- u'type': u'spice'}}
- TEST.servers.spice_console_data = console
-
- # Floating IPs
- def generate_fip(conf):
- return floating_ips.FloatingIP(floating_ips.FloatingIPManager(None),
- conf)
-
- fip_1 = {'id': 1,
- 'fixed_ip': '10.0.0.4',
- 'instance_id': server_1.id,
- 'ip': '58.58.58.58',
- 'pool': 'pool1'}
- fip_2 = {'id': 2,
- 'fixed_ip': None,
- 'instance_id': None,
- 'ip': '58.58.58.58',
- 'pool': 'pool2'}
- TEST.api_floating_ips.add(generate_fip(fip_1), generate_fip(fip_2))
-
- TEST.floating_ips.add(NetFloatingIp(generate_fip(fip_1)),
- NetFloatingIp(generate_fip(fip_2)))
-
- # Floating IP with UUID id (for Floating IP with Neutron Proxy)
- fip_3 = {'id': str(uuid.uuid4()),
- 'fixed_ip': '10.0.0.4',
- 'instance_id': server_1.id,
- 'ip': '58.58.58.58',
- 'pool': 'pool1'}
- fip_4 = {'id': str(uuid.uuid4()),
- 'fixed_ip': None,
- 'instance_id': None,
- 'ip': '58.58.58.58',
- 'pool': 'pool2'}
- TEST.api_floating_ips_uuid.add(generate_fip(fip_3), generate_fip(fip_4))
-
- TEST.floating_ips_uuid.add(NetFloatingIp(generate_fip(fip_3)),
- NetFloatingIp(generate_fip(fip_4)))
-
- # Usage
- usage_vals = {"tenant_id": TEST.tenant.id,
- "instance_name": server_1.name,
- "flavor_name": flavor_1.name,
- "flavor_vcpus": flavor_1.vcpus,
- "flavor_disk": flavor_1.disk,
- "flavor_ram": flavor_1.ram}
- usage_obj = usage.Usage(usage.UsageManager(None),
- json.loads(USAGE_DATA % usage_vals))
- TEST.usages.add(usage_obj)
-
- usage_2_vals = {"tenant_id": tenant3.id,
- "instance_name": server_3.name,
- "flavor_name": flavor_1.name,
- "flavor_vcpus": flavor_1.vcpus,
- "flavor_disk": flavor_1.disk,
- "flavor_ram": flavor_1.ram}
- usage_obj_2 = usage.Usage(usage.UsageManager(None),
- json.loads(USAGE_DATA % usage_2_vals))
- TEST.usages.add(usage_obj_2)
-
- volume_snapshot = vol_snaps.Snapshot(vol_snaps.SnapshotManager(None),
- {'id': '40f3fabf-3613-4f5e-90e5-6c9a08333fc3',
- 'display_name': 'test snapshot',
- 'display_description': 'vol snap!',
- 'size': 40,
- 'status': 'available',
- 'volume_id': '41023e92-8008-4c8b-8059-7f2293ff3775'})
- TEST.volume_snapshots.add(volume_snapshot)
-
- cert_data = {'private_key': 'private',
- 'data': 'certificate_data'}
- certificate = certs.Certificate(certs.CertificateManager(None), cert_data)
- TEST.certs.add(certificate)
-
- # Availability Zones
- TEST.availability_zones.add(
- availability_zones.AvailabilityZone(
- availability_zones.AvailabilityZoneManager(None),
- {'zoneName': 'nova', 'zoneState': {'available': True}}
- )
- )
-
- # hypervisors
- hypervisor_1 = hypervisors.Hypervisor(hypervisors.HypervisorManager(None),
- {
- "service": {"host": "devstack001", "id": 3},
- "vcpus_used": 1,
- "hypervisor_type": "QEMU",
- "local_gb_used": 20,
- "hypervisor_hostname": "devstack001",
- "memory_mb_used": 1500,
- "memory_mb": 2000,
- "current_workload": 0,
- "vcpus": 1,
- "cpu_info": '{"vendor": "Intel", "model": "core2duo",'
- '"arch": "x86_64", "features": ["lahf_lm"'
- ', "rdtscp"], "topology": {"cores": 1, "t'
- 'hreads": 1, "sockets": 1}}',
- "running_vms": 1,
- "free_disk_gb": 9,
- "hypervisor_version": 1002000,
- "disk_available_least": 6,
- "local_gb": 29,
- "free_ram_mb": 500,
- "id": 1
- }
- )
- TEST.hypervisors.add(hypervisor_1)
-
- # Services
- service_1 = services.Service(services.ServiceManager(None),
- {
- "status": "enabled",
- "binary": "nova-conductor",
- "zone": "internal",
- "state": "up",
- "updated_at": "2013-07-08T05:21:00.000000",
- "host": "devstack001",
- "disabled_reason": None
- }
- )
-
- service_2 = services.Service(services.ServiceManager(None),
- {
- "status": "enabled",
- "binary": "nova-compute",
- "zone": "nova",
- "state": "up",
- "updated_at": "2013-07-08T05:20:51.000000",
- "host": "devstack001",
- "disabled_reason": None
- }
- )
- TEST.services.add(service_1)
- TEST.services.add(service_2)
-
- # Aggregates
- aggregate_1 = aggregates.Aggregate(aggregates.AggregateManager(None),
- {
- "name": "foo",
- "availability_zone": None,
- "deleted": 0,
- "created_at": "2013-07-04T13:34:38.000000",
- "updated_at": None,
- "hosts": ["foo", "bar"],
- "deleted_at": None,
- "id": 1,
- "metadata": {
- "foo": "testing",
- "bar": "testing"
- }
- }
- )
-
- aggregate_2 = aggregates.Aggregate(aggregates.AggregateManager(None),
- {
- "name": "bar",
- "availability_zone": "testing",
- "deleted": 0,
- "created_at": "2013-07-04T13:34:38.000000",
- "updated_at": None,
- "hosts": ["foo", "bar"],
- "deleted_at": None,
- "id": 2,
- "metadata": {
- "foo": "testing",
- "bar": "testing"
- }
- }
- )
-
- TEST.aggregates.add(aggregate_1)
- TEST.aggregates.add(aggregate_2)
diff --git a/openstack_dashboard/test/test_data/swift_data.py b/openstack_dashboard/test/test_data/swift_data.py
deleted file mode 100644
index 2feef810..00000000
--- a/openstack_dashboard/test/test_data/swift_data.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from openstack_dashboard.api import swift
-
-from openstack_dashboard.test.test_data.utils import TestDataContainer
-
-
-def data(TEST):
- TEST.containers = TestDataContainer()
- TEST.objects = TestDataContainer()
-
- container_1 = swift.Container(dict(name=u"container_one\u6346"))
- container_2 = swift.Container(dict(name=u"container_two\u6346"))
- TEST.containers.add(container_1, container_2)
-
- object_dict = {"name": u"test_object\u6346",
- "content_type": u"text/plain",
- "bytes": 128,
- "last_modified": None,
- "hash": u"object_hash"}
- obj_dicts = [object_dict]
- obj_data = "Fake Data"
-
- for obj_dict in obj_dicts:
- swift_object = swift.StorageObject(obj_dict,
- container_1.name,
- data=obj_data)
- TEST.objects.add(swift_object)
diff --git a/openstack_dashboard/test/test_data/tuskar_data.py b/openstack_dashboard/test/test_data/tuskar_data.py
deleted file mode 100644
index b6890cc5..00000000
--- a/openstack_dashboard/test/test_data/tuskar_data.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from collections import namedtuple
-
-from openstack_dashboard.api.tuskar import Capacity
-from openstack_dashboard.api.tuskar import Flavor
-from openstack_dashboard.api.tuskar import FlavorTemplate
-from openstack_dashboard.api.tuskar import Node
-from openstack_dashboard.api.tuskar import Rack
-from openstack_dashboard.api.tuskar import ResourceClass
-
-from openstack_dashboard.test.test_data.utils import TestDataContainer
-
-
-def data(TEST):
- FlavorStruct = namedtuple('FlavorStruct', 'id name\
- capacities')
- CapacityStruct = namedtuple('CapacityStruct', 'name value unit')
- TEST.tuskar_flavor_templates = TestDataContainer()
- flavor_template_1 = FlavorTemplate(FlavorStruct(
- id="1",
- name='nano',
- capacities=[
- Capacity(CapacityStruct(
- name='cpu',
- unit='',
- value='1')),
- Capacity(CapacityStruct(
- name='memory',
- unit='MB',
- value='64')),
- Capacity(CapacityStruct(
- name='storage',
- unit='MB',
- value='128')),
- Capacity(CapacityStruct(
- name='ephemeral_disk',
- unit='GB',
- value='0')),
- Capacity(CapacityStruct(
- name='swap_disk',
- unit='GB',
- value='0'))]))
- flavor_template_2 = FlavorTemplate(FlavorStruct(
- id="2",
- name='large',
- capacities=[]))
- TEST.tuskar_flavor_templates.add(flavor_template_1, flavor_template_2)
-
- # Flavors
- TEST.tuskar_flavors = TestDataContainer()
- flavor_1 = Flavor(FlavorStruct(
- id="1",
- name='nano',
- capacities=[]))
- flavor_2 = Flavor(FlavorStruct(
- id="2",
- name='large',
- capacities=[]))
- TEST.tuskar_flavors.add(flavor_1, flavor_2)
-
- # Resource Classes
- TEST.tuskar_resource_classes = TestDataContainer()
-
- ResourceClassStruct = namedtuple('ResourceClassStruct', 'id service_type\
- name racks')
- resource_class_1 = ResourceClass(ResourceClassStruct(
- id="1",
- service_type="compute",
- racks=[{'id': 1}],
- name="rclass1"))
-
- resource_class_2 = ResourceClass(ResourceClassStruct(
- id="2",
- service_type="compute",
- racks=[],
- name="rclass2"))
-
- """
- # FIXME to make code below work, every @property has to have
- # setter defined in API model
- flavors = []
- all_flavors = []
- resources = []
- all_resources = []
-
- @resources.setter
- def resources(self, value):
- self._resources = value
- resource_class_1.resources = resources
- resource_class_2.resources = resources
-
- resource_class_1.all_resources = all_resources
- resource_class_2.all_resources = all_resources
-
- resource_class_1.flavors = flavors
- resource_class_2.flavors = flavors
-
- resource_class_1.all_flavors = all_flavors
- resource_class_2.all_flavors = all_flavors
- """
-
- TEST.tuskar_resource_classes.add(resource_class_1, resource_class_2)
-
- #Racks
- TEST.tuskar_racks = TestDataContainer()
- # FIXME: Struct is used to provide similar object-like behaviour
- # as is provided by tuskarclient
- RackStruct = namedtuple('RackStruct', 'id name nodes resource_class\
- location subnet state')
- rack_1 = Rack(RackStruct(
- id="1",
- name='rack1',
- location='location',
- subnet='192.168.1.0/24',
- state='provisioned',
- nodes=[{'id': '1'}, {'id': '2'}, {'id': '3'}, {'id': '4'}],
- resource_class={'id': '1'}))
-
- TEST.tuskar_racks.add(rack_1)
-
- # Nodes
- TEST.nodes = TestDataContainer()
- TEST.unracked_nodes = TestDataContainer()
-
- NodeStruct = namedtuple('RackStruct', 'id name prov_mac_address')
- node_1 = Node(NodeStruct(
- id="1",
- name="node1",
- prov_mac_address="00-B0-D0-86-AB-F7"))
- node_2 = Node(NodeStruct(
- id="2",
- name="node2",
- prov_mac_address="00-B0-D0-86-AB-F8"))
- node_3 = Node(NodeStruct(
- id="3",
- name="node3",
- prov_mac_address="00-B0-D0-86-AB-F9"))
- node_4 = Node(NodeStruct(
- id="4",
- name="node4",
- prov_mac_address="00-B0-D0-86-AB-F0"))
- node_5 = Node(NodeStruct(
- id="5",
- name="node5",
- prov_mac_address="00-B0-D0-86-AB-F1"))
-
- TEST.nodes.add(node_1, node_2, node_3, node_4)
- TEST.unracked_nodes.add(node_5)
diff --git a/openstack_dashboard/test/test_data/utils.py b/openstack_dashboard/test/test_data/utils.py
deleted file mode 100644
index 3509cd65..00000000
--- a/openstack_dashboard/test/test_data/utils.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-def load_test_data(load_onto=None):
- from openstack_dashboard.test.test_data import cinder_data
- from openstack_dashboard.test.test_data import exceptions
- from openstack_dashboard.test.test_data import glance_data
- from openstack_dashboard.test.test_data import heat_data
- from openstack_dashboard.test.test_data import keystone_data
- from openstack_dashboard.test.test_data import neutron_data
- from openstack_dashboard.test.test_data import nova_data
- from openstack_dashboard.test.test_data import swift_data
- from openstack_dashboard.test.test_data import tuskar_data
-
- # The order of these loaders matters, some depend on others.
- loaders = (exceptions.data,
- keystone_data.data,
- glance_data.data,
- nova_data.data,
- cinder_data.data,
- neutron_data.data,
- swift_data.data,
- heat_data.data,
- tuskar_data.data)
- if load_onto:
- for data_func in loaders:
- data_func(load_onto)
- return load_onto
- else:
- return TestData(*loaders)
-
-
-class TestData(object):
- """
- Holder object for test data. Any functions passed to the init method
- will be called with the ``TestData`` object as their only argument. They
- can then load data onto the object as desired.
-
- The idea is to use the instantiated object like this::
-
- >>> import glance_data
- >>> TEST = TestData(glance_data.data)
- >>> TEST.images.list()
- ... [<Image: visible_image>, <Image: invisible_image>]
- >>> TEST.images.first()
- ... <Image: visible_image>
-
- You can load as little or as much data as you like as long as the loaders
- don't conflict with each other.
-
- See the :class:`~horizon.tests.test_data.utils.TestDataContainer` class
- for a list of available methods.
- """
- def __init__(self, *args):
- for data_func in args:
- data_func(self)
-
-
-class TestDataContainer(object):
- """ A container for test data objects.
-
- The behavior of this class is meant to mimic a "manager" class, which
- has convenient shortcuts for common actions like "list", "filter", "get",
- and "add".
- """
- def __init__(self):
- self._objects = []
-
- def add(self, *args):
- """ Add a new object to this container.
-
- Generally this method should only be used during data loading, since
- adding data during a test can affect the results of other tests.
- """
- for obj in args:
- if obj not in self._objects:
- self._objects.append(obj)
-
- def list(self):
- """ Returns a list of all objects in this container. """
- return self._objects
-
- def filter(self, filtered=None, **kwargs):
- """
- Returns objects in this container whose attributes match the given
- keyword arguments.
- """
- if filtered is None:
- filtered = self._objects
- try:
- key, value = kwargs.popitem()
- except KeyError:
- # We're out of filters, return
- return filtered
-
- def get_match(obj):
- return hasattr(obj, key) and getattr(obj, key) == value
-
- return self.filter(filtered=filter(get_match, filtered), **kwargs)
-
- def get(self, **kwargs):
- """
- Returns the single object in this container whose attributes match
- the given keyword arguments. An error will be raised if the arguments
- provided don't return exactly one match.
- """
- matches = self.filter(**kwargs)
- if not matches:
- raise Exception("No matches found.")
- elif len(matches) > 1:
- raise Exception("Multiple matches found.")
- else:
- return matches.pop()
-
- def first(self):
- """ Returns the first object from this container. """
- return self._objects[0]
-
- def count(self):
- return len(self._objects)
diff --git a/openstack_dashboard/test/tests/__init__.py b/openstack_dashboard/test/tests/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/test/tests/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/test/tests/error_pages.py b/openstack_dashboard/test/tests/error_pages.py
deleted file mode 100644
index a889605e..00000000
--- a/openstack_dashboard/test/tests/error_pages.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2012 OpenStack, LLC.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from os import path
-
-from django.conf import settings
-
-from openstack_dashboard.test import helpers as test
-
-
-class ErrorPageTests(test.TestCase):
- """ Tests for error pages """
- urls = 'openstack_dashboard.test.error_pages_urls'
-
- def test_500_error(self):
- TEMPLATE_DIRS = (path.join(settings.ROOT_PATH, 'templates'),)
- with self.settings(TEMPLATE_DIRS=TEMPLATE_DIRS):
- response = self.client.get('/500/')
- self.assertTrue('Server error' in response.content)
diff --git a/openstack_dashboard/test/tests/quotas.py b/openstack_dashboard/test/tests/quotas.py
deleted file mode 100644
index 0da699f5..00000000
--- a/openstack_dashboard/test/tests/quotas.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-# Copyright (c) 2012 X.commerce, a business unit of eBay Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from __future__ import absolute_import
-
-from django import http
-from mox import IsA
-
-from openstack_dashboard import api
-from openstack_dashboard.api import cinder
-from openstack_dashboard.test import helpers as test
-from openstack_dashboard.usage import quotas
-
-
-class QuotaTests(test.APITestCase):
-
- def get_usages(self, with_volume=True):
- quotas = {'injected_file_content_bytes': {'quota': 1},
- 'metadata_items': {'quota': 1},
- 'injected_files': {'quota': 1},
- 'security_groups': {'quota': 10},
- 'security_group_rules': {'quota': 20},
- 'fixed_ips': {'quota': 10},
- 'ram': {'available': 8976, 'used': 1024, 'quota': 10000},
- 'floating_ips': {'available': 0, 'used': 2, 'quota': 1},
- 'instances': {'available': 8, 'used': 2, 'quota': 10},
- 'cores': {'available': 8, 'used': 2, 'quota': 10}}
- if with_volume:
- quotas.update({'volumes': {'available': 0, 'used': 3, 'quota': 1},
- 'snapshots': {'available': 0, 'used': 3,
- 'quota': 1},
- 'gigabytes': {'available': 920, 'used': 80,
- 'quota': 1000}})
- return quotas
-
- @test.create_stubs({api.nova: ('server_list',
- 'flavor_list',
- 'tenant_quota_get',),
- api.network: ('tenant_floating_ip_list',),
- quotas: ('is_service_enabled',),
- cinder: ('volume_list', 'volume_snapshot_list',
- 'tenant_quota_get',)})
- def test_tenant_quota_usages(self):
- servers = [s for s in self.servers.list()
- if s.tenant_id == self.request.user.tenant_id]
-
- quotas.is_service_enabled(IsA(http.HttpRequest),
- 'volume').AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \
- .AndReturn(self.quotas.first())
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn(self.floating_ips.list())
- api.nova.server_list(IsA(http.HttpRequest)) \
- .AndReturn([servers, False])
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
- .AndReturn(self.snapshots.list())
- cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \
- .AndReturn(self.cinder_quotas.first())
-
- self.mox.ReplayAll()
-
- quota_usages = quotas.tenant_quota_usages(self.request)
- expected_output = self.get_usages()
-
- # Compare internal structure of usages to expected.
- self.assertEquals(quota_usages.usages, expected_output)
-
- @test.create_stubs({api.nova: ('server_list',
- 'flavor_list',
- 'tenant_quota_get',),
- api.network: ('tenant_floating_ip_list',),
- quotas: ('is_service_enabled',)})
- def test_tenant_quota_usages_without_volume(self):
- servers = [s for s in self.servers.list()
- if s.tenant_id == self.request.user.tenant_id]
-
- quotas.is_service_enabled(IsA(http.HttpRequest),
- 'volume').AndReturn(False)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \
- .AndReturn(self.quotas.first())
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn(self.floating_ips.list())
- api.nova.server_list(IsA(http.HttpRequest)) \
- .AndReturn([servers, False])
-
- self.mox.ReplayAll()
-
- quota_usages = quotas.tenant_quota_usages(self.request)
- expected_output = self.get_usages(with_volume=False)
-
- # Compare internal structure of usages to expected.
- self.assertEquals(quota_usages.usages, expected_output)
-
- @test.create_stubs({api.nova: ('server_list',
- 'flavor_list',
- 'tenant_quota_get',),
- api.network: ('tenant_floating_ip_list',),
- quotas: ('is_service_enabled',)})
- def test_tenant_quota_usages_no_instances_running(self):
- quotas.is_service_enabled(IsA(http.HttpRequest),
- 'volume').AndReturn(False)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \
- .AndReturn(self.quotas.first())
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn([])
- api.nova.server_list(IsA(http.HttpRequest)).AndReturn([[], False])
-
- self.mox.ReplayAll()
-
- quota_usages = quotas.tenant_quota_usages(self.request)
- expected_output = self.get_usages(with_volume=False)
-
- expected_output.update({
- 'ram': {'available': 10000, 'used': 0, 'quota': 10000},
- 'floating_ips': {'available': 1, 'used': 0, 'quota': 1},
- 'instances': {'available': 10, 'used': 0, 'quota': 10},
- 'cores': {'available': 10, 'used': 0, 'quota': 10}})
-
- # Compare internal structure of usages to expected.
- self.assertEquals(quota_usages.usages, expected_output)
-
- @test.create_stubs({api.nova: ('server_list',
- 'flavor_list',
- 'tenant_quota_get',),
- api.network: ('tenant_floating_ip_list',),
- quotas: ('is_service_enabled',),
- cinder: ('volume_list', 'volume_snapshot_list',
- 'tenant_quota_get',)})
- def test_tenant_quota_usages_unlimited_quota(self):
- inf_quota = self.quotas.first()
- inf_quota['ram'] = -1
- servers = [s for s in self.servers.list()
- if s.tenant_id == self.request.user.tenant_id]
-
- quotas.is_service_enabled(IsA(http.HttpRequest),
- 'volume').AndReturn(True)
- api.nova.flavor_list(IsA(http.HttpRequest)) \
- .AndReturn(self.flavors.list())
- api.nova.tenant_quota_get(IsA(http.HttpRequest), '1') \
- .AndReturn(inf_quota)
- api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
- .AndReturn(self.floating_ips.list())
- api.nova.server_list(IsA(http.HttpRequest)) \
- .AndReturn([servers, False])
- cinder.volume_list(IsA(http.HttpRequest)) \
- .AndReturn(self.volumes.list())
- cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
- .AndReturn(self.snapshots.list())
- cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \
- .AndReturn(self.cinder_quotas.first())
-
- self.mox.ReplayAll()
-
- quota_usages = quotas.tenant_quota_usages(self.request)
- expected_output = self.get_usages()
- expected_output.update({'ram': {'available': float("inf"),
- 'used': 1024,
- 'quota': float("inf")}})
-
- # Compare internal structure of usages to expected.
- self.assertEquals(quota_usages.usages, expected_output)
diff --git a/openstack_dashboard/test/tests/selenium.py b/openstack_dashboard/test/tests/selenium.py
deleted file mode 100644
index 83db95e6..00000000
--- a/openstack_dashboard/test/tests/selenium.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from horizon.test import helpers as test
-
-
-class BrowserTests(test.SeleniumTestCase):
- def test_splash(self):
- self.selenium.get(self.live_server_url)
- button = self.selenium.find_element_by_tag_name("button")
- self.assertEqual(button.text, "Sign In")
diff --git a/openstack_dashboard/test/tests/utils.py b/openstack_dashboard/test/tests/utils.py
deleted file mode 100644
index 2096b267..00000000
--- a/openstack_dashboard/test/tests/utils.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright (c) 2013 OpenStack Foundation
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import uuid
-
-from openstack_dashboard.test import helpers as test
-from openstack_dashboard.utils.filters import get_int_or_uuid
-
-
-class UtilsFilterTests(test.TestCase):
- def test_accept_valid_integer(self):
- val = 100
- ret = get_int_or_uuid(val)
- self.assertEqual(val, ret)
-
- def test_accept_valid_integer_string(self):
- val = '100'
- ret = get_int_or_uuid(val)
- self.assertEqual(int(val), ret)
-
- def test_accept_valid_uuid(self):
- val = str(uuid.uuid4())
- ret = get_int_or_uuid(val)
- self.assertEqual(val, ret)
-
- def test_reject_random_string(self):
- val = '55WbJTpJDf'
- self.assertRaises(ValueError, get_int_or_uuid, val)
diff --git a/openstack_dashboard/urls.py b/openstack_dashboard/urls.py
deleted file mode 100644
index c4faae79..00000000
--- a/openstack_dashboard/urls.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-URL patterns for the OpenStack Dashboard.
-"""
-
-from django.conf import settings
-from django.conf.urls.defaults import include
-from django.conf.urls.defaults import patterns
-from django.conf.urls.defaults import url
-from django.conf.urls.static import static
-from django.contrib.staticfiles.urls import staticfiles_urlpatterns
-
-import horizon
-
-
-urlpatterns = patterns('',
- url(r'^$', 'openstack_dashboard.views.splash', name='splash'),
- url(r'^auth/', include('openstack_auth.urls')),
- url(r'', include(horizon.urls))
-)
-
-# Development static app and project media serving using the staticfiles app.
-urlpatterns += staticfiles_urlpatterns()
-
-# Convenience function for serving user-uploaded media during
-# development. Only active if DEBUG==True and the URL prefix is a local
-# path. Production media should NOT be served by Django.
-urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
-
-if settings.DEBUG:
- urlpatterns += patterns('',
- url(r'^500/$', 'django.views.defaults.server_error')
- )
diff --git a/openstack_dashboard/usage/__init__.py b/openstack_dashboard/usage/__init__.py
deleted file mode 100644
index a1f6ef61..00000000
--- a/openstack_dashboard/usage/__init__.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from openstack_dashboard.usage.base import BaseUsage
-from openstack_dashboard.usage.base import GlobalUsage
-from openstack_dashboard.usage.base import ProjectUsage
-from openstack_dashboard.usage.tables import BaseUsageTable
-from openstack_dashboard.usage.tables import GlobalUsageTable
-from openstack_dashboard.usage.tables import ProjectUsageTable
-from openstack_dashboard.usage.views import UsageView
-
-assert BaseUsage
-assert ProjectUsage
-assert GlobalUsage
-assert UsageView
-assert BaseUsageTable
-assert ProjectUsageTable
-assert GlobalUsageTable
diff --git a/openstack_dashboard/usage/base.py b/openstack_dashboard/usage/base.py
deleted file mode 100644
index 4e540981..00000000
--- a/openstack_dashboard/usage/base.py
+++ /dev/null
@@ -1,317 +0,0 @@
-from __future__ import division
-
-from csv import DictWriter
-from csv import writer
-
-import datetime
-import logging
-from StringIO import StringIO
-
-from django.http import HttpResponse
-from django import template as django_template
-from django.utils import timezone
-from django.utils.translation import ugettext_lazy as _
-from django import VERSION
-
-from horizon import exceptions
-from horizon import forms
-from horizon import messages
-
-from openstack_dashboard import api
-from openstack_dashboard.usage import quotas
-
-
-LOG = logging.getLogger(__name__)
-
-
-class BaseUsage(object):
- show_terminated = False
-
- def __init__(self, request, project_id=None):
- self.project_id = project_id or request.user.tenant_id
- self.request = request
- self.summary = {}
- self.usage_list = []
- self.limits = {}
- self.quotas = {}
-
- @property
- def today(self):
- return timezone.now()
-
- @staticmethod
- def get_start(year, month, day):
- start = datetime.datetime(year, month, day, 0, 0, 0)
- return timezone.make_aware(start, timezone.utc)
-
- @staticmethod
- def get_end(year, month, day):
- end = datetime.datetime(year, month, day, 23, 59, 59)
- return timezone.make_aware(end, timezone.utc)
-
- def get_instances(self):
- instance_list = []
- [instance_list.extend(u.server_usages) for u in self.usage_list]
- return instance_list
-
- def get_date_range(self):
- if not hasattr(self, "start") or not hasattr(self, "end"):
- args_start = args_end = (self.today.year,
- self.today.month,
- self.today.day)
- form = self.get_form()
- if form.is_valid():
- start = form.cleaned_data['start']
- end = form.cleaned_data['end']
- args_start = (start.year,
- start.month,
- start.day)
- args_end = (end.year,
- end.month,
- end.day)
- elif form.is_bound:
- messages.error(self.request,
- _("Invalid date format: "
- "Using today as default."))
- self.start = self.get_start(*args_start)
- self.end = self.get_end(*args_end)
- return self.start, self.end
-
- def init_form(self):
- today = datetime.date.today()
- first = datetime.date(day=1, month=today.month, year=today.year)
- if today.day in range(5):
- self.end = first - datetime.timedelta(days=1)
- self.start = datetime.date(day=1,
- month=self.end.month,
- year=self.end.year)
- else:
- self.end = today
- self.start = first
- return self.start, self.end
-
- def get_form(self):
- if not hasattr(self, 'form'):
- if any(key in ['start', 'end'] for key in self.request.GET):
- # bound form
- self.form = forms.DateForm(self.request.GET)
- else:
- # non-bound form
- init = self.init_form()
- self.form = forms.DateForm(initial={'start': init[0],
- 'end': init[1]})
- return self.form
-
- def get_limits(self):
- try:
- self.limits = api.nova.tenant_absolute_limits(self.request)
- except:
- exceptions.handle(self.request,
- _("Unable to retrieve limit information."))
-
- def get_usage_list(self, start, end):
- raise NotImplementedError("You must define a get_usage method.")
-
- def summarize(self, start, end):
- if start <= end and start <= self.today:
- # The API can't handle timezone aware datetime, so convert back
- # to naive UTC just for this last step.
- start = timezone.make_naive(start, timezone.utc)
- end = timezone.make_naive(end, timezone.utc)
- try:
- self.usage_list = self.get_usage_list(start, end)
- except:
- exceptions.handle(self.request,
- _('Unable to retrieve usage information.'))
- elif end < start:
- messages.error(self.request,
- _("Invalid time period. The end date should be "
- "more recent than the start date."))
- elif start > self.today:
- messages.error(self.request,
- _("Invalid time period. You are requesting "
- "data from the future which may not exist."))
-
- for project_usage in self.usage_list:
- project_summary = project_usage.get_summary()
- for key, value in project_summary.items():
- self.summary.setdefault(key, 0)
- self.summary[key] += value
-
- def get_quotas(self):
- try:
- self.quotas = quotas.tenant_quota_usages(self.request)
- except:
- exceptions.handle(self.request,
- _("Unable to retrieve quota information."))
-
- def csv_link(self):
- form = self.get_form()
- data = {}
- if hasattr(form, "cleaned_data"):
- data = form.cleaned_data
- if not ('start' in data and 'end' in data):
- data = {"start": self.today.date(), "end": self.today.date()}
- return "?start=%s&end=%s&format=csv" % (data['start'],
- data['end'])
-
-
-class GlobalUsage(BaseUsage):
- show_terminated = True
-
- def get_usage_list(self, start, end):
- return api.nova.usage_list(self.request, start, end)
-
-
-class ProjectUsage(BaseUsage):
- attrs = ('memory_mb', 'vcpus', 'uptime',
- 'hours', 'local_gb')
-
- def get_usage_list(self, start, end):
- show_terminated = self.request.GET.get('show_terminated',
- self.show_terminated)
- instances = []
- terminated_instances = []
- usage = api.nova.usage_get(self.request, self.project_id, start, end)
- # Attribute may not exist if there are no instances
- if hasattr(usage, 'server_usages'):
- now = self.today
- for server_usage in usage.server_usages:
- # This is a way to phrase uptime in a way that is compatible
- # with the 'timesince' filter. (Use of local time intentional.)
- server_uptime = server_usage['uptime']
- total_uptime = now - datetime.timedelta(seconds=server_uptime)
- server_usage['uptime_at'] = total_uptime
- if server_usage['ended_at'] and not show_terminated:
- terminated_instances.append(server_usage)
- else:
- instances.append(server_usage)
- usage.server_usages = instances
- return (usage,)
-
-
-class CsvDataMixin(object):
-
- """
- CSV data Mixin - provides handling for CSV data
-
- .. attribute:: columns
-
- A list of CSV column definitions. If omitted - no column titles
- will be shown in the result file. Optional.
- """
- def __init__(self):
- self.out = StringIO()
- super(CsvDataMixin, self).__init__()
- if hasattr(self, "columns"):
- self.writer = DictWriter(self.out, map(self.encode, self.columns))
- self.is_dict = True
- else:
- self.writer = writer(self.out)
- self.is_dict = False
-
- def write_csv_header(self):
- if self.is_dict:
- try:
- self.writer.writeheader()
- except AttributeError:
- # For Python<2.7
- self.writer.writerow(dict(zip(
- self.writer.fieldnames,
- self.writer.fieldnames)))
-
- def write_csv_row(self, args):
- if self.is_dict:
- self.writer.writerow(dict(zip(
- self.writer.fieldnames, map(self.encode, args))))
- else:
- self.writer.writerow(map(self.encode, args))
-
- def encode(self, value):
- # csv and StringIO cannot work with mixed encodings,
- # so encode all with utf-8
- return unicode(value).encode('utf-8')
-
-
-class BaseCsvResponse(CsvDataMixin, HttpResponse):
-
- """
- Base CSV response class. Provides handling of CSV data.
-
- """
-
- def __init__(self, request, template, context, content_type, **kwargs):
- super(BaseCsvResponse, self).__init__()
- self['Content-Disposition'] = 'attachment; filename="%s"' % (
- kwargs.get("filename", "export.csv"),)
- self['Content-Type'] = content_type
- self.context = context
- self.header = None
- if template:
- # Display some header info if provided as a template
- header_template = django_template.loader.get_template(template)
- context = django_template.RequestContext(request, self.context)
- self.header = header_template.render(context)
-
- if self.header:
- self.out.write(self.encode(self.header))
-
- self.write_csv_header()
-
- for row in self.get_row_data():
- self.write_csv_row(row)
-
- self.out.flush()
- self.content = self.out.getvalue()
- self.out.close()
-
- def get_row_data(self):
- raise NotImplementedError("You must define a get_row_data method on %s"
- % self.__class__.__name__)
-
-if VERSION >= (1, 5, 0):
-
- from django.http import StreamingHttpResponse
-
- class BaseCsvStreamingResponse(CsvDataMixin, StreamingHttpResponse):
-
- """
- Base CSV Streaming class. Provides streaming response for CSV data.
- """
-
- def __init__(self, request, template, context, content_type, **kwargs):
- super(BaseCsvStreamingResponse, self).__init__()
- self['Content-Disposition'] = 'attachment; filename="%s"' % (
- kwargs.get("filename", "export.csv"),)
- self['Content-Type'] = content_type
- self.context = context
- self.header = None
- if template:
- # Display some header info if provided as a template
- header_template = django_template.loader.get_template(template)
- context = django_template.RequestContext(request, self.context)
- self.header = header_template.render(context)
-
- self._closable_objects.append(self.out)
-
- self.streaming_content = self.get_content()
-
- def buffer(self):
- buf = self.out.getvalue()
- self.out.truncate(0)
- return buf
-
- def get_content(self):
- if self.header:
- self.out.write(self.encode(self.header))
-
- self.write_csv_header()
- yield self.buffer()
-
- for row in self.get_row_data():
- self.write_csv_row(row)
- yield self.buffer()
-
- def get_row_data(self):
- raise NotImplementedError("You must define a get_row_data method "
- "on %s" % self.__class__.__name__)
diff --git a/openstack_dashboard/usage/quotas.py b/openstack_dashboard/usage/quotas.py
deleted file mode 100644
index fcd51154..00000000
--- a/openstack_dashboard/usage/quotas.py
+++ /dev/null
@@ -1,158 +0,0 @@
-from collections import defaultdict
-import itertools
-
-from horizon import exceptions
-from horizon.utils.memoized import memoized
-
-from openstack_dashboard.api.base import is_service_enabled
-from openstack_dashboard.api.base import QuotaSet
-from openstack_dashboard.api import cinder
-from openstack_dashboard.api import network
-from openstack_dashboard.api import nova
-
-NOVA_QUOTA_FIELDS = ("metadata_items",
- "cores",
- "instances",
- "injected_files",
- "injected_file_content_bytes",
- "ram",
- "floating_ips",
- "fixed_ips",
- "security_groups",
- "security_group_rules",)
-
-CINDER_QUOTA_FIELDS = ("volumes",
- "snapshots",
- "gigabytes",)
-
-QUOTA_FIELDS = NOVA_QUOTA_FIELDS + CINDER_QUOTA_FIELDS
-
-
-class QuotaUsage(dict):
- """ Tracks quota limit, used, and available for a given set of quotas."""
-
- def __init__(self):
- self.usages = defaultdict(dict)
-
- def __getitem__(self, key):
- return self.usages[key]
-
- def __setitem__(self, key, value):
- raise NotImplemented("Directly setting QuotaUsage values is not "
- "supported. Please use the add_quota and "
- "tally methods.")
-
- def __repr__(self):
- return repr(dict(self.usages))
-
- def add_quota(self, quota):
- """ Adds an internal tracking reference for the given quota. """
- if quota.limit is None or quota.limit == -1:
- # Handle "unlimited" quotas.
- self.usages[quota.name]['quota'] = float("inf")
- self.usages[quota.name]['available'] = float("inf")
- else:
- self.usages[quota.name]['quota'] = int(quota.limit)
-
- def tally(self, name, value):
- """ Adds to the "used" metric for the given quota. """
- value = value or 0 # Protection against None.
- # Start at 0 if this is the first value.
- if 'used' not in self.usages[name]:
- self.usages[name]['used'] = 0
- # Increment our usage and update the "available" metric.
- self.usages[name]['used'] += int(value) # Fail if can't coerce to int.
- self.update_available(name)
-
- def update_available(self, name):
- """ Updates the "available" metric for the given quota. """
- available = self.usages[name]['quota'] - self.usages[name]['used']
- if available < 0:
- available = 0
- self.usages[name]['available'] = available
-
-
-def _get_quota_data(request, method_name, disabled_quotas=None,
- tenant_id=None):
- quotasets = []
- if not tenant_id:
- tenant_id = request.user.tenant_id
- quotasets.append(getattr(nova, method_name)(request, tenant_id))
- qs = QuotaSet()
- if disabled_quotas is None:
- disabled_quotas = get_disabled_quotas(request)
- if 'volumes' not in disabled_quotas:
- quotasets.append(getattr(cinder, method_name)(request, tenant_id))
- for quota in itertools.chain(*quotasets):
- if quota.name not in disabled_quotas:
- qs[quota.name] = quota.limit
- return qs
-
-
-def get_default_quota_data(request, disabled_quotas=None, tenant_id=None):
- return _get_quota_data(request,
- "default_quota_get",
- disabled_quotas=disabled_quotas,
- tenant_id=tenant_id)
-
-
-def get_tenant_quota_data(request, disabled_quotas=None, tenant_id=None):
- return _get_quota_data(request,
- "tenant_quota_get",
- disabled_quotas=disabled_quotas,
- tenant_id=tenant_id)
-
-
-def get_disabled_quotas(request):
- disabled_quotas = []
- if not is_service_enabled(request, 'volume'):
- disabled_quotas.extend(CINDER_QUOTA_FIELDS)
- return disabled_quotas
-
-
-@memoized
-def tenant_quota_usages(request):
- # Get our quotas and construct our usage object.
- disabled_quotas = get_disabled_quotas(request)
-
- usages = QuotaUsage()
- for quota in get_tenant_quota_data(request,
- disabled_quotas=disabled_quotas):
- usages.add_quota(quota)
-
- # Get our usages.
- floating_ips = network.tenant_floating_ip_list(request)
- flavors = dict([(f.id, f) for f in nova.flavor_list(request)])
- instances, has_more = nova.server_list(request)
- # Fetch deleted flavors if necessary.
- missing_flavors = [instance.flavor['id'] for instance in instances
- if instance.flavor['id'] not in flavors]
- for missing in missing_flavors:
- if missing not in flavors:
- try:
- flavors[missing] = nova.flavor_get(request, missing)
- except:
- flavors[missing] = {}
- exceptions.handle(request, ignore=True)
-
- usages.tally('instances', len(instances))
- usages.tally('floating_ips', len(floating_ips))
-
- if 'volumes' not in disabled_quotas:
- volumes = cinder.volume_list(request)
- snapshots = cinder.volume_snapshot_list(request)
- usages.tally('gigabytes', sum([int(v.size) for v in volumes]))
- usages.tally('volumes', len(volumes))
- usages.tally('snapshots', len(snapshots))
-
- # Sum our usage based on the flavors of the instances.
- for flavor in [flavors[instance.flavor['id']] for instance in instances]:
- usages.tally('cores', getattr(flavor, 'vcpus', None))
- usages.tally('ram', getattr(flavor, 'ram', None))
-
- # Initialise the tally if no instances have been launched yet
- if len(instances) == 0:
- usages.tally('cores', 0)
- usages.tally('ram', 0)
-
- return usages
diff --git a/openstack_dashboard/usage/tables.py b/openstack_dashboard/usage/tables.py
deleted file mode 100644
index cca842c3..00000000
--- a/openstack_dashboard/usage/tables.py
+++ /dev/null
@@ -1,72 +0,0 @@
-from django.core import urlresolvers
-from django.template.defaultfilters import floatformat
-from django.template.defaultfilters import timesince
-from django.utils.translation import ugettext_lazy as _
-
-from horizon import tables
-from horizon.templatetags.sizeformat import mbformat
-
-
-class CSVSummary(tables.LinkAction):
- name = "csv_summary"
- verbose_name = _("Download CSV Summary")
- classes = ("btn-download",)
-
- def get_link_url(self, usage=None):
- return self.table.kwargs['usage'].csv_link()
-
-
-class BaseUsageTable(tables.DataTable):
- vcpus = tables.Column('vcpus', verbose_name=_("VCPUs"))
- disk = tables.Column('local_gb', verbose_name=_("Disk"))
- memory = tables.Column('memory_mb',
- verbose_name=_("RAM"),
- filters=(mbformat,),
- attrs={"data-type": "size"})
- hours = tables.Column('vcpu_hours', verbose_name=_("VCPU Hours"),
- filters=(lambda v: floatformat(v, 2),))
-
-
-class GlobalUsageTable(BaseUsageTable):
- project = tables.Column('project_name', verbose_name=_("Project Name"))
- disk_hours = tables.Column('disk_gb_hours',
- verbose_name=_("Disk GB Hours"),
- filters=(lambda v: floatformat(v, 2),))
-
- def get_object_id(self, datum):
- return datum.tenant_id
-
- class Meta:
- name = "global_usage"
- verbose_name = _("Usage Summary")
- columns = ("project", "vcpus", "disk", "memory",
- "hours", "disk_hours")
- table_actions = (CSVSummary,)
- multi_select = False
-
-
-def get_instance_link(datum):
- view = "horizon:project:instances:detail"
- if datum.get('instance_id', False):
- return urlresolvers.reverse(view, args=(datum.get('instance_id'),))
- else:
- return None
-
-
-class ProjectUsageTable(BaseUsageTable):
- instance = tables.Column('name',
- verbose_name=_("Instance Name"),
- link=get_instance_link)
- uptime = tables.Column('uptime_at',
- verbose_name=_("Uptime"),
- filters=(timesince,))
-
- def get_object_id(self, datum):
- return datum.get('instance_id', id(datum))
-
- class Meta:
- name = "project_usage"
- verbose_name = _("Usage Summary")
- columns = ("instance", "vcpus", "disk", "memory", "uptime")
- table_actions = (CSVSummary,)
- multi_select = False
diff --git a/openstack_dashboard/usage/views.py b/openstack_dashboard/usage/views.py
deleted file mode 100644
index 702ea357..00000000
--- a/openstack_dashboard/usage/views.py
+++ /dev/null
@@ -1,56 +0,0 @@
-import logging
-
-from horizon import tables
-from openstack_dashboard.usage.base import BaseUsage
-
-
-LOG = logging.getLogger(__name__)
-
-
-class UsageView(tables.DataTableView):
- usage_class = None
- show_terminated = True
-
- def __init__(self, *args, **kwargs):
- super(UsageView, self).__init__(*args, **kwargs)
- if not issubclass(self.usage_class, BaseUsage):
- raise AttributeError("You must specify a usage_class attribute "
- "which is a subclass of BaseUsage.")
-
- def get_template_names(self):
- if self.request.GET.get('format', 'html') == 'csv':
- return ".".join((self.template_name.rsplit('.', 1)[0], 'csv'))
- return self.template_name
-
- def get_content_type(self):
- if self.request.GET.get('format', 'html') == 'csv':
- return "text/csv"
- return "text/html"
-
- def get_data(self):
- project_id = self.kwargs.get('project_id', self.request.user.tenant_id)
- self.usage = self.usage_class(self.request, project_id)
- self.usage.summarize(*self.usage.get_date_range())
- self.usage.get_limits()
- self.kwargs['usage'] = self.usage
- return self.usage.usage_list
-
- def get_context_data(self, **kwargs):
- context = super(UsageView, self).get_context_data(**kwargs)
- context['table'].kwargs['usage'] = self.usage
- context['form'] = self.usage.form
- context['usage'] = self.usage
- return context
-
- def render_to_response(self, context, **response_kwargs):
- if self.request.GET.get('format', 'html') == 'csv':
- render_class = self.csv_response_class
- response_kwargs.setdefault("filename", "usage.csv")
- else:
- render_class = self.response_class
- resp = render_class(request=self.request,
- template=self.get_template_names(),
- context=context,
- content_type=self.get_content_type(),
- **response_kwargs)
- return resp
diff --git a/openstack_dashboard/utils/__init__.py b/openstack_dashboard/utils/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/openstack_dashboard/utils/__init__.py
+++ /dev/null
diff --git a/openstack_dashboard/utils/filters.py b/openstack_dashboard/utils/filters.py
deleted file mode 100644
index 47f18719..00000000
--- a/openstack_dashboard/utils/filters.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 NEC Corporation All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import uuid
-
-
-def get_int_or_uuid(value):
- """Check if a value is valid as UUID or an integer.
-
- This method is mainly used to convert floating IP id to the
- appropriate type. For floating IP id, integer is used in Nova's
- original implementation, but UUID is used in Neutron based one.
- """
- try:
- uuid.UUID(value)
- return value
- except (ValueError, AttributeError):
- return int(value)
diff --git a/openstack_dashboard/views.py b/openstack_dashboard/views.py
deleted file mode 100644
index 75227e69..00000000
--- a/openstack_dashboard/views.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 Nebula, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from django import shortcuts
-from django.views.decorators import vary
-
-import horizon
-
-from openstack_auth.views import Login
-
-
-def get_user_home(user):
- if user.is_superuser:
- return horizon.get_dashboard('admin').get_absolute_url()
- return horizon.get_dashboard('project').get_absolute_url()
-
-
-@vary.vary_on_cookie
-def splash(request):
- if request.user.is_authenticated():
- return shortcuts.redirect(get_user_home(request.user))
- form = Login(request)
- request.session.clear()
- request.session.set_test_cookie()
- return shortcuts.render(request, 'splash.html', {'form': form})
diff --git a/openstack_dashboard/wsgi/django.wsgi b/openstack_dashboard/wsgi/django.wsgi
deleted file mode 100644
index 1e92a4d2..00000000
--- a/openstack_dashboard/wsgi/django.wsgi
+++ /dev/null
@@ -1,15 +0,0 @@
-import logging
-import os
-import sys
-import django.core.handlers.wsgi
-from django.conf import settings
-
-# Add this file path to sys.path in order to import settings
-sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), '../..'))
-os.environ['DJANGO_SETTINGS_MODULE'] = 'openstack_dashboard.settings'
-sys.stdout = sys.stderr
-
-DEBUG = False
-
-application = django.core.handlers.wsgi.WSGIHandler()
-